请考虑以下示例:
-Thread 1-
y.store (20, memory_order_relaxed);
x.store (10, memory_order_release);
-Thread 2-
if (x.load(memory_order_acquire) == 10) {
assert (y.load(memory_order_relaxed) == 20)
y.store (10, memory_order_release)
}
-Thread 3-
if (y.load(memory_order_acquire) == 10)
assert (x.load(memory_order_relaxed) == 10)
在此示例中,第二个assert
将会触发(我是否正确?)。是因为x
之前的帖子2中没有y.store (10, memory_order_release)
的商店?
(在cppreference.com中他们说这句关于release
的句子:“具有此内存顺序的存储操作执行释放操作:先前写入其他内存位置对于执行消耗或获取的线程变得可见在同一个地方。“)
我可以将thread2中的商店订单从y
更改为release
以解决问题吗?
答案 0 :(得分:2)
您的示例未完成,因为您尚未指定x&的初始值年。但是我们假设启动所有线程的线程都已初始化为0.
然后,如果线程2对y进行存储,它必须从线程1的存储读取到x并与之同步。如果线程3的加载从y读取线程2的存储到y,它也必须同步。因此,线程1中的x存储必须在线程3中的加载之前发生,并且必须在初始化存储到x之后发生。因此,线程3的x.load必须得到值10.在没有消耗之前发生的事情是传递的。
我建议在这些示例中使用CDSChecker来查看可能的值。