std::atomic_compare_exchange_weak, std::atomic_compare_exchange_strong, std::atomic_compare_exchange_weak_explicit, std::atomic_compare_exchange_strong_explicit
定義於標頭檔案 <atomic> |
||
template< class T > bool atomic_compare_exchange_weak |
(1) | (C++11 起) |
template< class T > bool atomic_compare_exchange_weak |
(2) | (C++11 起) |
template< class T > bool atomic_compare_exchange_strong |
(3) | (C++11 起) |
template< class T > bool atomic_compare_exchange_strong |
(4) | (C++11 起) |
template< class T > bool atomic_compare_exchange_weak_explicit |
(5) | (C++11 起) |
template< class T > bool atomic_compare_exchange_weak_explicit |
(6) | (C++11 起) |
template< class T > bool atomic_compare_exchange_strong_explicit |
(7) | (C++11 起) |
template< class T > bool atomic_compare_exchange_strong_explicit |
(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 的成員函式中
如果 failure比 success 更強,或者(C++17 前)是 std::memory_order_release 和 std::memory_order_acq_rel 之一,則行為未定義。
目錄 |
[編輯] 引數
obj | - | 指向要測試和修改的原子物件的指標 |
expected | - | 指向期望在原子物件中找到的值的指標 |
desired | - | 如果原子物件符合預期,則儲存到原子物件中的值 |
成功 | - | 如果比較成功,則讀-改-寫操作的記憶體同步順序 |
失敗 | - | 如果比較失敗,則載入操作的記憶體同步順序 |
[編輯] 返回值
比較結果:如果 *obj 等於 *expected 則為 true,否則為 false。
[編輯] 注意
std::atomic_compare_exchange_weak
和 std::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> 的公開成員函式) | |
(C++11)(C++11) |
原子地將原子物件的值替換為非原子引數,並返回原子的舊值 (函式模板) |
為 std::shared_ptr 特化原子操作 (函式模板) | |
C 文件 用於 atomic_compare_exchange, atomic_compare_exchange_explicit
|