C++ 关于c+中内存排序的示例+;
考虑以下示例:C++ 关于c+中内存排序的示例+;,c++,multithreading,concurrency,atomic,C++,Multithreading,Concurrency,Atomic,考虑以下示例: -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) } -Threa
-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
将触发(我是否正确?)。这是因为在y.store(10,内存\u顺序\u释放)
之前,线程2中没有存储到x
(在cppreference.com中,他们说这句话是关于释放的:,“使用此内存顺序的存储操作执行释放操作:对其他内存位置的先前写入对在同一位置上进行消费或获取的线程可见。”)
我可以将thread2中的存储顺序从release
更改为sec/cst
以解决此问题吗?您的示例不完整,因为您没有指定x&y的初始值。但是,让我们假设启动所有线程的线程已将两者初始化为0
然后,如果线程2对y进行存储,那么它必须已经从线程1的存储读取到x并与之同步。如果线程3的load from y将线程2的存储读取到y,那么它也必须同步。因此,线程1中的x存储必须在线程3中的加载之前发生,并且必须在初始化x存储之后发生。因此,线程3的x.load的值必须为10。在没有消费的情况下发生在前面是可传递的
我建议在这些示例中使用CDSChecker来查看哪些值是可能的。请参阅其中的“总体摘要”部分的示例,他们说第二个断言将触发。GCC示例声明了不同的内存顺序,因此它不相关。没有断言可以触发。。有趣的是,即使thread2中存储到y
的顺序更改为relaxed
,仍然不会触发assert
,因为这不会中断事件发生之前的链(线程3仍然需要使用acquire
)