名稱空間
變體
操作

std::atomic_compare_exchange_weak, std::atomic_compare_exchange_strong, std::atomic_compare_exchange_weak_explicit, std::atomic_compare_exchange_strong_explicit

來自 cppreference.com
< cpp‎ | atomic
 
 
併發支援庫
執行緒
(C++11)
(C++20)
this_thread 名稱空間
(C++11)
(C++11)
(C++11)
協同取消
互斥
(C++11)
通用鎖管理
(C++11)
(C++11)
(C++11)
(C++11)
(C++11)
條件變數
(C++11)
訊號量
門閂和屏障
(C++20)
(C++20)
期值
(C++11)
(C++11)
(C++11)
(C++11)
安全回收
(C++26)
危險指標
原子型別
(C++11)
(C++20)
原子型別的初始化
(C++11)(C++20 中已棄用)
(C++11)(C++20 中已棄用)
記憶體排序
(C++11)(C++26 中已棄用)
原子操作的自由函式
atomic_compare_exchange_weakatomic_compare_exchange_weak_explicitatomic_compare_exchange_strongatomic_compare_exchange_strong_explicit
(C++11)(C++11)(C++11)(C++11)
原子標誌的自由函式
 
定義於標頭檔案 <atomic>
template< class T >

bool atomic_compare_exchange_weak
    ( std::atomic<T>* obj, typename std::atomic<T>::value_type* expected,

      typename std::atomic<T>::value_type desired ) noexcept;
(1) (C++11 起)
template< class T >

bool atomic_compare_exchange_weak
    ( volatile std::atomic<T>* obj,
      typename std::atomic<T>::value_type* expected,

      typename std::atomic<T>::value_type desired ) noexcept;
(2) (C++11 起)
template< class T >

bool atomic_compare_exchange_strong
    ( std::atomic<T>* obj, typename std::atomic<T>::value_type* expected,

      typename std::atomic<T>::value_type desired ) noexcept;
(3) (C++11 起)
template< class T >

bool atomic_compare_exchange_strong
    ( volatile std::atomic<T>* obj,
      typename std::atomic<T>::value_type* expected,

      typename std::atomic<T>::value_type desired ) noexcept;
(4) (C++11 起)
template< class T >

bool atomic_compare_exchange_weak_explicit
    ( std::atomic<T>* obj, typename std::atomic<T>::value_type* expected,
      typename std::atomic<T>::value_type desired,

      std::memory_order success, std::memory_order failure ) noexcept;
(5) (C++11 起)
template< class T >

bool atomic_compare_exchange_weak_explicit
    ( volatile std::atomic<T>* obj,
      typename std::atomic<T>::value_type* expected,
      typename std::atomic<T>::value_type desired,

      std::memory_order success, std::memory_order failure ) noexcept;
(6) (C++11 起)
template< class T >

bool atomic_compare_exchange_strong_explicit
    ( std::atomic<T>* obj, typename std::atomic<T>::value_type* expected,
      typename std::atomic<T>::value_type desired,

      std::memory_order success, std::memory_order failure ) noexcept;
(7) (C++11 起)
template< class T >

bool atomic_compare_exchange_strong_explicit
    ( volatile std::atomic<T>* obj,
      typename std::atomic<T>::value_type* expected,
      typename std::atomic<T>::value_type desired,

      std::memory_order success, std::memory_order failure ) noexcept;
(8) (C++11 起)

原子地比較 obj 所指向物件的物件表示(C++20 前)值表示(C++20 起)expected 所指向物件的物件表示(C++20 前)值表示(C++20 起),如果它們是位等價的,則用 desired 替換前者(執行讀-改-寫操作)。否則,將 obj 所指向的實際值載入到 *expected 中(執行載入操作)。

 過載  記憶體模型用於
 讀-改-寫 操作  載入操作
(1-4) std::memory_order_seq_cst  std::memory_order_seq_cst 
(5-8) 成功 失敗

這些函式定義在 std::atomic成員函式

1,2) obj->compare_exchange_weak(*expected, desired)
3,4) obj->compare_exchange_strong(*expected, desired)
5,6) obj->compare_exchange_weak(*expected, desired, success, failure)
7,8) obj->compare_exchange_strong(*expected, desired, success, failure)

如果 failuresuccess 更強,或者(C++17 前)std::memory_order_releasestd::memory_order_acq_rel 之一,則行為未定義。

目錄

[編輯] 引數

obj - 指向要測試和修改的原子物件的指標
expected - 指向期望在原子物件中找到的值的指標
desired - 如果原子物件符合預期,則儲存到原子物件中的值
成功 - 如果比較成功,則讀-改-寫操作的記憶體同步順序
失敗 - 如果比較失敗,則載入操作的記憶體同步順序

[編輯] 返回值

比較結果:如果 *obj 等於 *expected 則為 true,否則為 false

[編輯] 注意

std::atomic_compare_exchange_weakstd::atomic_compare_exchange_weak_explicit (弱版本)允許虛假失敗,即即使 *obj 等於 *expected,它們也可能表現得像不相等。當比較和交換操作在迴圈中時,它們在某些平臺上會提供更好的效能。

當弱比較和交換需要迴圈而強比較和交換不需要時,強版本更可取,除非 T 的物件表示可能包含填充位,(C++20 前)陷阱位,或對相同值提供多個物件表示(例如浮點 NaN)。在這些情況下,弱比較和交換通常有效,因為它會快速收斂到某個穩定的物件表示。

對於包含在某些成員的值表示中但不在其他成員的值表示中的位的聯合體,比較和交換可能總是失敗,因為當這些填充位不參與活動成員的值表示時,它們具有不確定的值。

從不參與物件值表示的填充位會被忽略。

(C++20 起)

[編輯] 示例

比較和交換操作常被用作無鎖資料結構的基本構建塊。

#include <atomic>
 
template<class T>
struct node
{
    T data;
    node* next;
    node(const T& data) : data(data), next(nullptr) {}
};
 
template<class T>
class stack
{
    std::atomic<node<T>*> head;
public:
    void push(const T& data)
    {
        node<T>* new_node = new node<T>(data);
 
        // put the current value of head into new_node->next
        new_node->next = head.load(std::memory_order_relaxed);
 
        // now make new_node the new head, but if the head
        // is no longer what's stored in new_node->next
        // (some other thread must have inserted a node just now)
        // then put that new head into new_node->next and try again
        while (!std::atomic_compare_exchange_weak_explicit(
                   &head, &new_node->next, new_node,
                   std::memory_order_release, std::memory_order_relaxed))
            ; // the body of the loop is empty
// note: the above loop is not thread-safe in at least
// GCC prior to 4.8.3 (bug 60272), clang prior to 2014-05-05 (bug 18899)
// MSVC prior to 2014-03-17 (bug 819819). See member function version for workaround
    }
};
 
int main()
{
    stack<int> s;
    s.push(1);
    s.push(2);
    s.push(3);
}

[編輯] 缺陷報告

下列更改行為的缺陷報告追溯地應用於以前出版的 C++ 標準。

缺陷報告 應用於 釋出時的行為 正確的行為
P0558R1 C++11 因為要求精確型別匹配
T 是從多個引數推匯出來的
T 僅從
obj 中推導

[編輯] 參閱

原子地將原子物件的值與非原子引數進行比較,如果相等則執行原子交換,否則執行原子載入
(std::atomic<T> 的公開成員函式) [編輯]
原子地將原子物件的值替換為非原子引數,並返回原子的舊值
(函式模板) [編輯]
為 std::shared_ptr 特化原子操作
(函式模板)
C 文件 用於 atomic_compare_exchange, atomic_compare_exchange_explicit