[英]C++ atomic acquire / release operations what it actually means
我正在瀏覽此頁面並試圖了解 Memory model 同步模式。 在下面從那里提取的示例中:
-Thread 1- -Thread 2-
y = 1 if (x.load() == 2)
x.store (2); assert (y == 1)
到哪個聲明在線程 1 中存儲到“y”之前發生到“x”的存儲。這里的“y”變量是普通全局變量還是原子變量?
此外,如果線程 2 中 'x' 的加載獲得線程 1 中發生的存儲的結果,則它必須全部看到線程 1 中存儲之前發生的所有操作,甚至是不相關的操作。
那么 x.store() 操作意味着所有對 memory 的讀/寫都應該更新相應的 memory 數據值是什么意思?
然后對於 std::memory_order_relaxed 意味着“沒有線程可以指望來自另一個線程的特定排序”——這是什么意思——重新排序將由編譯器完成,即使 y.store() 是,y 的值也不會被更新叫什么?
-Thread 1-
y.store (20, memory_order_relaxed)
x.store (10, memory_order_relaxed)
-Thread 2-
if (x.load (memory_order_relaxed) == 10)
{
assert (y.load(memory_order_relaxed) == 20) /* assert A */
y.store (10, memory_order_relaxed)
}
-Thread 3-
if (y.load (memory_order_relaxed) == 10)
assert (x.load(memory_order_relaxed) == 10) /* assert B */
For Acquire / release memory model 類似於順序一致模式,只是它只對因變量應用 happens-before 關系。
Assuming 'x' and 'y' are initially 0:
-Thread 1-
y.store (20, memory_order_release);
-Thread 2-
x.store (10, memory_order_release);
-Thread 3-
assert (y.load (memory_order_acquire) == 20 && x.load (memory_order_acquire) == 0)
-Thread 4-
assert (y.load (memory_order_acquire) == 0 && x.load (memory_order_acquire) == 10)
用明確的術語來說是什么意思?
-Thread 1- -Thread 2-
y = 1 if (x.load() == 2)
x.store (2); assert (y == 1)
y = 1;
發生在x.store (2);
. 如果有另一個線程 3操作變量 y ,斷言可能會由於另一個線程而失敗。-Thread 1-
y.store (20, memory_order_relaxed) // 1-1
x.store (10, memory_order_relaxed) // 1-2
-Thread 2-
if (x.load (memory_order_relaxed) == 10) // 2-1
{
assert (y.load(memory_order_relaxed) == 20) /* assert A */
y.store (10, memory_order_relaxed) // 2-2
}
-Thread 3-
if (y.load (memory_order_relaxed) == 10) // 3-1
assert (x.load(memory_order_relaxed) == 10) /* assert B */
x
& y
彼此沒有任何依賴關系。 因此編譯器可能會更改線程 1的執行順序,這與std::memory_order_seq_cst不同,其中y.store(20)
必須在x.store(10)
發生之前執行。1-2
的副作用。 即使線程 2必須看到它的副作用以便將 10 存儲到 y 中,編譯器也不保證指令的副作用必須在線程之間同步(發生之前)assert(y <= z)
保證通過。-Thread 1-
x.store (1, memory_order_relaxed)
x.store (2, memory_order_relaxed)
-Thread 2-
y = x.load (memory_order_relaxed)
z = x.load (memory_order_relaxed)
assert (y <= z)
2-2。 是否重新排序將由編譯器完成,即使調用 y.store() 也可能不會更新 y 的值?
不。 正如我在 2. 中所描述的,這意味着編譯器可能會更改不具有數據依賴性的指令順序。 當然,在y.store()
時必須更新y 。 畢竟,這是原子指令的定義。
Assuming 'x' and 'y' are initially 0:
-Thread 1-
y.store (20, memory_order_release);
-Thread 2-
x.store (10, memory_order_release);
-Thread 3-
assert (y.load (memory_order_acquire) == 20 && x.load (memory_order_acquire) == 0)
-Thread 4-
assert (y.load (memory_order_acquire) == 0 && x.load (memory_order_acquire) == 10)
y.store()
必須發生在x.store()
之前,反之亦然。y.store()
發生在x.store()
之前。 所以線程 4必須在x.load() == 10
之前看到y.load() == 20
。 因此斷言失敗。 如果線程 4的斷言通過,也會發生同樣的事情。y.load()
→線程 1 y.store()
→線程 3 y.load()
→線程 3 x.load()
→線程 4 x.load()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.