我正在嘗試了解 C 中涉及原子變數的執行順序,并且我有以下代碼。
根據cppreference,我有以下推理:
C 在執行時強制執行 1->2 順序因為在同一執行緒中的獲取加載之前不能移動加載/存盤。
C 執行時強制執行 3->4 順序 與 1 相同的原因
C 執行時強制執行 2->3 順序
因為 2 是對 y 的釋放存盤,而 3 是來自 y 的獲取加載。所以 2 應該對 3 可見。因此,2 應該在 3 之前執行,并且 3 將讀取 2 的寫入結果。
C 在執行時強制執行 4->1 順序與 3 相同的原因
從推理 1/2/3 可以推匯出 的執行順序1 -> 2 -> 3 -> 4,它會破壞推理 4。從推理 1/2/4 可以推匯出 的執行順序3 -> 4 -> 1 -> 2,它會破壞推理 3。
這里似乎有沖突。
int main() {
while(true) {
std::atomic<int> x, y;
x.store(10);
y.store(20);
auto f1 = [&]() {
int r1 = x.load(std::memory_order_acquire); // 1
y.store(r1, std::memory_order_release); // 2
};
auto f2 = [&]() {
int r2 = y.load(std::memory_order_acquire); // 3
x.store(r2, std::memory_order_release); // 4
};
std::thread t1(f1);
std::thread t2(f2);
t1.join();
t2.join();
printf("%d %d\n", x.load(), y.load());
}
}
- 編輯 -
我關于為什么 2 必須在 3 之前發生的推理:
- 從 preshing 開始,y.store(rel) 與 y.load(acq) 同步。
- 然后根據cppreference,我們可以在y.store(rel) 執行緒間發生-before y.load(acq)。
- 然后 y.store(rel) 發生在 y.load(acq) 之前。
- 所以 y.store(rel) 必須在 y.load(acq) 之前發生
uj5u.com熱心網友回復:
1將“發生在”2之前,3將“發生在”4之前。這部分是正確的。
但是,要讓 3 與 2“同步”(以及“發生在其后”),它必須成功讀取 2 寫入的值。
如果它沒有讀取該值(因為它最終在 2 之前運行),則不會發生同步,并且不會對 4 相對于 1 進行排序。在這種情況下,3 被稱為“在2之前的一致性排序” .
這同樣適用于從 4 讀取值的 1。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/421219.html
標籤:
