问题描述
类似于我的上一个问题,请考虑这段代码
Similar to my previous question, consider this code
-- Initially --
std::atomic<int> x{0};
std::atomic<int> y{0};
-- Thread 1 --
x.store(1, std::memory_order_release);
-- Thread 2 --
y.store(2, std::memory_order_release);
-- Thread 3 --
int r1 = x.load(std::memory_order_acquire); // x first
int r2 = y.load(std::memory_order_acquire);
-- Thread 4 --
int r3 = y.load(std::memory_order_acquire); // y first
int r4 = x.load(std::memory_order_acquire);
奇怪的结果 r1==1, r2==0
和 r3==2, r4==0
是否可能在这C++11 内存模型下的情况?如果我将所有 std::memory_order_acq_rel
替换为 std::memory_order_relaxed
会怎样?
Is the weird outcome r1==1, r2==0
and r3==2, r4==0
possible in this case under the C++11 memory model? What if I were to replace all std::memory_order_acq_rel
by std::memory_order_relaxed
?
在 x86 上似乎禁止这样的结果,请参阅 this SO question 但我问的是 C++11 内存- 一般模型.
On x86 such an outcome seems to be forbidden, see this SO question but I am asking about the C++11 memory-model in general.
额外问题:
我们都同意,对于std::memory_order_seq_cst
,C++11 中不允许出现奇怪的结果.现在,赫伯·萨特在他著名的 atomic<>
-weapons talk @ 42:30 std::memory_order_seq_cst
就像 std::memory_order_acq_rel
但是 std::memory_order_acquire
-loads 在 std::memory_order_release
-writes 之前可能不会移动.我看不出上面例子中的这个额外约束如何防止奇怪的结果.谁能解释一下?
We all agree, that with std::memory_order_seq_cst
the weird outcome would not be allowed in C++11. Now, Herb Sutter said in his famous atomic<>
-weapons talk @ 42:30 that std::memory_order_seq_cst
is just like std::memory_order_acq_rel
but std::memory_order_acquire
-loads may not move before std::memory_order_release
-writes. I cannot see how this additional constraint in the above example would prevent the weird outcome. Can anyone explain?
推荐答案
问题中更新的1 代码(带有 x
和 y代码>在线程 4 中交换)实际上测试所有线程都同意全局存储顺序.
The updated1 code in the question (with loads of x
and y
swapped in Thread 4) does actually test that all threads agree on a global store order.
在 C++11 内存模型下,结果 r1==1, r2==0, r3==2, r4==0
是允许的,实际上可以在 POWER 上观察到.
Under the C++11 memory model, the outcome r1==1, r2==0, r3==2, r4==0
is allowed and in fact observable on POWER.
在 x86 上,这种结果是不可能的,因为其他处理器以一致的顺序看到存储".这种结果在顺序一致执行中也是不允许的.
On x86 this outcome is not possible, because there "stores are seen in a consistent order by other processors". This outcome is also not allowed in a sequential consistent execution.
脚注 1:这个问题最初是让两位读者阅读 x
然后是 y
.顺序一致的执行是:
Footnote 1: The question originally had both readers read x
then y
. A sequentially consistent execution of that is:
-- Initially --
std::atomic<int> x{0};
std::atomic<int> y{0};
-- Thread 4 --
int r3 = x.load(std::memory_order_acquire);
-- Thread 1 --
x.store(1, std::memory_order_release);
-- Thread 3 --
int r1 = x.load(std::memory_order_acquire);
int r2 = y.load(std::memory_order_acquire);
-- Thread 2 --
y.store(2, std::memory_order_release);
-- Thread 4 --
int r4 = y.load(std::memory_order_acquire);
这导致 r1==1, r2==0, r3==0, r4==2
.因此,这不是一个奇怪的结果.
This results in r1==1, r2==0, r3==0, r4==2
. Hence, this is not a weird outcome at all.
为了能够说每个读者看到不同的商店订单,我们需要他们以相反的顺序阅读,以排除最后一个商店只是被延迟.
To be able to say that each reader saw a different store order, we need them to read in opposite orders to rule out the last store simply being delayed.
这篇关于其他线程是否总是以相同的顺序看到对不同线程中不同位置的两次原子写入?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!