多核心與同步

在上方的程式碼中,執行緒1準備好data後以flag通知,執行緒2看到flag後讀取data。在弱記憶體一致性模型的CPU上,要讓執行緒2確實讀到42,下列何者是必要的做法?

// 執行緒1         // 執行緒2
data = 42;           while (flag == 0) { }
flag = 1;            print(data);
  1. A把data的型別從int改為long
  2. B將對flag的寫入設為釋放(release)、對flag的讀取設為取得(acquire),以保證順序
  3. C不要在執行緒2的迴圈中寫任何東西
查看答案與解析

正確答案:B. 將對flag的寫入設為釋放(release)、對flag的讀取設為取得(acquire),以保證順序

在弱模型中,執行緒1的兩個寫入可能看起來被調換,執行緒2對data的讀取也可能比對flag的讀取更早進行,因此可能發生flag已是1而data仍是舊值的情形。若將對flag的寫入設為釋放,就能保證在它之前的寫入會先被看到;若將對flag的讀取設為取得,則在它之後的讀取不會搶先進行。

  • A. 即使改變型別,也無法保證順序。
  • B. 正確。保證data的寫入比flag先被看到。
  • C. 迴圈的內容與順序的保證無關。
練習這個領域 前往領域頁面

多核心與同步的其他題目

  1. 關於具有取得(acquire)與釋放(release)意義的記憶體操作,下列何者正確?
  2. 在C語言中,僅對執行緒之間傳遞的旗標變數加上volatile,仍不足以作為同步,其理由下列何者正確?
  3. C11的_Atomic或C++11的std::atomic可以指定記憶體順序(memory order),其理由下列何者正確?
  4. 比較以一把鎖保護整個大型資料結構的「粗粒度鎖」,與以不同的鎖保護各個部分的「細粒度鎖」,下列說明何者正確?
  5. 關於無鎖(lock-free)演算法的性質,下列何者正確?

這個領域的比較