原子性加減通常是用CAS(Compare and Swap)完成的,與平台相關。CAS的基本形式是:CAS(addr,old,new),當addr中存放的值等於old時,用new對其替換
std::atomic::compare_exchange_weak
bool compare_exchange_weak (T& expected, T val, memory_order sync = memory_order_seq_cst) volatile noexcept; bool compare_exchange_weak (T& expected, T val, memory_order sync = memory_order_seq_cst) noexcept; bool compare_exchange_weak (T& expected, T val, memory_order success, memory_order failure) volatile noexcept; bool compare_exchange_weak (T& expected, T val, memory_order success, memory_order failure) noexcept;
當前值與期望值相等時,修改當前值為設定值,返回true
當前值與期望值不等時,將期望值修改為當前值,返回false
這個函數可能在滿足true的情況下仍然返回false,所以只能在循環里使用,否則可以使用它的strong版本
實現無鎖鏈表的例子
#include <iostream> // std::cout #include <atomic> // std::atomic #include <thread> // std::thread #include <vector> // std::vector // a simple global linked list: struct Node { int value; Node* next; }; std::atomic<Node*> list_head (nullptr); void append (int val) { // append an element to the list Node* oldHead = list_head; Node* newNode = new Node {val,oldHead}; // what follows is equivalent to: list_head = newNode, but in a thread-safe way: while (!list_head.compare_exchange_weak(oldHead,newNode)) { newNode->next = oldHead; } } int main () { // spawn 10 threads to fill the linked list: std::vector<std::thread> threads; for (int i=0; i<30; ++i) threads.push_back(std::thread(append,i)); for (auto& th : threads) th.join(); // print contents: for (Node* it = list_head; it!=nullptr; it=it->next) std::cout << ' ' << it->value; std::cout << '\n'; // cleanup: Node* it; while (it=list_head) {list_head=it->next; delete it;} return 0; }
結果可能是:
mutian@mutian:~/soft/compile$ g++ -std=c++0x tt.c -lpthread
mutian@mutian:~/soft/compile$ ./a.out
29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 0 1