C++ 並行編程之memory_order


一.如果只是簡單地解決在多線程中對共享資源的讀寫並發問題,只需要用C++以下內容: 線程類 thread, 原子數據類模板 atomic<T> t, 互斥 mutex, 鎖 lock, 條件變量 condition_variables.

 
二.在此基礎上,如果想在並行編程中獲得更好的性能,尤其當使用的是一些弱內存順序的平台(比如PowerPC)的話,設定原子操作間的內存順序則很有必要.
 
 
C++11 加入了支持並行編程的原子操作模塊,而所有的原子操作都有一個參數 memory_order.
1.內存模型 簡介
內存模型是一個硬件上的概念,表示機器指令是以什么樣的順序被處理器執行的 (現代的處理器不是逐條處理機器指令的) .
#include <thread>
#include <atomic>
 
atomic<int> a;
atomic<int> b;
void threadHandle()
{
     int t = 1;
     a = t;
     b = 2; // b 的賦值不依賴 a
}

在上面的線程處理函數中的三行代碼,在寄存器中實際執行順序可能與代碼寫的順序不一致.在不同的機器平台下,處理器有可能對指令周期的執行順序優化(一個時鍾周期發射多條指令),就是說它可能讓 b 的賦值語句比 a 的賦值語句先執行.

此時,如果有一個線程在循環地打印 a 和 b 的值,那么結果並不總是 a == 1 和 b == 2.

 

2.如何保證指令執行順序

保證執行順序會犧牲一些執行效率,因為這意味着放棄了編譯器、處理器等的優化處理。

強順序的內存模型指: 代碼順序和寄存器實際執行的順序一致

弱順序的內存模型指: 寄存器實際執行的順序與代碼順序不一致,被處理器調整過

 

 

3.C++ 並行編程: 設定 指令執行順序

typedef enum memory_order {
    memory_order_relaxed,    // 不對執行順序做保證
    memory_order_acquire,    // 本線程中,所有后續的讀操作必須在本條原子操作完成后執行
    memory_order_release,    // 本線程中,所有之前的寫操作完成后才能執行本條原子操作
    memory_order_acq_rel,    // 同時包含 memory_order_acquire 和 memory_order_release
    memory_order_consume,    // 本線程中,所有后續的有關本原子類型的操作,必須在本條原子操作完成之后執行
    memory_order_seq_cst    // 全部存取都按順序執行
    } memory_order;

 

測試: 下面的代碼可能會打印出 a == 0; b == 2 這樣的結果

 1  #include <iostream>
 2  #include <thread>
 3  #include <atomic>
 4  
 5  atomic<int> a{ 0 };
 6  atomic<int> b{ 0 };
 7  void SetValue()
 8  {// atomic類模板中的函數都是原子操作.  int temp = a.load();相當於 int temp = a的原子操作
 9      int t = 1;
10      a.store(t, memory_order_relaxed); // 相當於 a = t的原子操作
11      b.store(2, memory_order_relaxed); // 相當於 b = 2的原子操作
12  }
13  void Observer()
14  {
15      cout << a << b << endl;
16  }
17  
18  int main()
19  {
20      thread T1(SetValue,0);
21      thread T2(Observer, 0);
22  
23      T1.join(); // 主線程(調用方)等待子線程 T1 執行完成,才能繼續執行,阻塞
24      T2.join(); // 同上,執行這一行前: T1已經結束,T2很可能也結束了
25  
26      return 0;
27  }
 
          
參考:C++ 多線程與內存模型資料匯
   memory order相關問題

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM