3 回答
TA贡献1843条经验 获得超7个赞
问题中的更新的1代码( 在线程4中进行了装载x和y交换)实际上测试了所有线程是否同意全局存储顺序。
在C ++ 11内存模型下,结果r1==1, r2==0, r3==2, r4==0是允许的,实际上在POWER上是可观察的。
在x86上,这种结果是不可能的,因为在那里“其他处理器以一致的顺序看到存储”。在顺序一致执行中也不允许此结果。
注:1:这个问题原本有两个读者阅读x,然后y。甲顺序一致的执行是:
-- 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。因此,这根本不是一个奇怪的结果。
为了说每个读者看到的商店顺序不同,我们需要他们以相反的顺序阅读,以排除最后一个商店只是被延迟了。
TA贡献1817条经验 获得超6个赞
是怪异的结果 r1==1, r2==0,并r3==0, r4==2有可能在C ++ 11内存模型下,这种情况下?
是。C ++内存模型允许这种奇怪的结果。
如果我要全部替换std::memory_order_acq_rel成该std::memory_order_relaxed怎么办?
如果更换所有memory_order_acquire和memory_order_release通过memory_order_relaxed,没有什么改变你的代码。
std::memory_order_seq_cst就像,std::memory_order_acq_rel但是std::memory_order_acquire-loads在std::memory_order_release-writes 之前可能不会移动。我看不到上面示例中的此附加约束如何防止出现奇怪的结果。
“ acquire-load可能不会在release-writes 之前移动。” 显示了顺序一致性约束(memory_order_seq_cst)的一方面。
在C ++内存模型中,它仅保证seq_cst具有acq_rel语义,并且所有 seq_cst原子访问不会多多少少都具有“总顺序”。当存在这样的“总顺序”时,我们无法得到怪异的结果,因为所有seq_cst原子访问都好像在单个线程上以任何交错顺序执行一样。
您先前的问题对待单个原子变量的“一致性” ,而这个问题要求所有原子变量的“一致性” 。C ++内存模型可确保单个原子变量甚至最弱的排序()的直观一致性relaxed,以及不同原子变量的“顺序一致性”,只要默认排序(seq_cst)。seq_cst如您所指出的那样,当您使用显式无序原子访问时,这可能是奇怪的结果。
- 3 回答
- 0 关注
- 529 浏览
添加回答
举报