三個用於並發編程的組件:
atomic,thread,asio(用於同步和異步io操作)
atomic
atomic,封裝了不同計算機硬件的底層操作原語,提供了跨平台的原子操作功能,解決並發競爭讀寫變量的困擾。
包含頭文件<boost/atomic.hpp>,
atomic可以把對類型T的操作原子化,T的要求:
1.標量類型,(算數,枚舉,指針)
2.只有平凡拷貝/轉移構造、賦值和析構函數的類,並且可以使用memcmp執行比操作,通常這樣的類都是pod
注:int memcmp(const void *buf1, const void *buf2, unsigned int count);
比較內存區域buf1和buf2的前count個字節。
atomic針對整數類型和指針類型進行特化,增加一些特殊操作。並定義了typedef。
基本操作:
兩種方式創建atomic對象:
1、atomic<int> a(10);
assert(a==10);//安全函數,若表達式不成立結束程序
2、atomic<long> L;
cout << L<<endl;//初始值不確定
最重要的兩個成員函數:
store()(operator=) 和 load()(operator T())以原子方式存取,不會因為並發訪問導致數據不一致。
1 boost::atomic<bool> b(1); 2 assert(b != 0); 3 std::cout << b << std::endl; 4 5 b.store(0);//存值 6 std::cout << b << std::endl; 7 8 boost::atomic<int> n1(100); 9 std::cout << n1.exchange(200) << std::endl;//交換兩個值,並且返回原值100 10 std::cout << n1 << std::endl; 11 12 13 n1 = 200; 14 int n2 = 201; 15 n1.compare_exchange_weak(n2, 313);//n1 和 n2相比較,相等就輸出313,如果不相等 n1 = n2 = 200; 16 std::cout << n1 << "\t" << n2 << std::endl; 17 //返回true 或 false 表示原值是否被修改 18 //區別為weak執行速度快,但有可能執行成功卻返回false 19 n2 = 201; 20 n1 = 2000; 21 n1.compare_exchange_strong(n2, 313);//功能與weak相同 22 std::cout << n1 << "\t" << n2 << std::endl; 23 24 //整數atomic用法 25 boost::atomic<int> n3(10); 26 std::cout << n3.fetch_add(10) << std::endl;//加法操作返回原值 27 std::cout << n3 << std::endl; 28 //重載操作符后,都是返回運算后的值 29 std::cout << n3++ << std::endl; 30 std::cout << ++n3 << std::endl; 31 //二進制 32 //它使用boost.preprocessor預處理元編程工具將一組或多組01數字在編譯期展開成為一個八進制數字。每個數字組之間可以用空格分隔,每組可以容納1個到8個0/1數字。 33 //這里特別要注意的是,數字組的長度一定不能超過八個,由於預處理器宏展開的限制,嵌套層次太深會導致無法通過編譯,報出一大堆錯誤。 34 //在編譯時展開,沒有任何運行時開銷 35 boost::atomic<int> n4{ BOOST_BINARY(1101) };// #include <boost/utility/binary.hpp> //或者 #include <boost/utility.hpp> 36 auto x = n4.fetch_and(BOOST_BINARY(0101));//邏輯與運算,返回原值n4 37 std::cout << x << std::endl; 38 std::cout << n4 << std::endl;
實際上每一個atomic<T>成員函數都有一個memory——order缺省參數,指定了原子操作的內存順序要求,不允許編譯器或者cpu核心為了優化而調整代碼或者指令的順序執行