我试图理解memory_order_seq_cst和memory_order_acq_rel之间的区别。关于SO的一些帖子已经涵盖了这个问题,但是,我不理解他们的答案。
memory_order_acq_rel提供相对于原子变量的读写顺序,而memory_order_seq_cst提供全局读写顺序。
它还包括一个例子
bool x= false;
bool y= false;
bool z= 0;
a() { x= true; }
b() { y= true; }
c() { while (!x); if (y) z++; }
d() { while (!y); if (x) z++; }
// kick off a, b, c, d, join all threads
assert(z!=0);
该代码段是cppreference.com上示例的骨架版本。我在Ideone和CoLiRu上编译了这个例子。在Ideone上,在memory_order_acq_rel和memory_order_seq_cst下,z可以是1或2。在CoLiRu,我只能得到2.它永远不会是0.
我的问题是:
答案 0 :(得分:0)
c ++ 11标准将seq_cst定义为
所有memory_order_seq_cst操作上应有一个总顺序S,与所有受影响位置的“先发生”顺序和修改顺序一致...
请注意,这些操作可能在不同的内存位置。如果使用acq_rel排序,则该顺序仅在相关的存储器位置上保持。
在您提供的示例中,我假设当您说“在memory_order_acq_rel下”时,意味着要说程序中的所有存储和装载都具有memory_order_acq_rel(与memory_order_seq_cst相同)。 memory_order_seq_cst的排序要求将对x
和y
的所有加载/存储操作强制执行总排序,这意味着x=true;
发生在y=true
或{{1之前}}发生在y=true
之前。因此x=true
的可能值为1或2。
而对于memory_order_acq_rel,如果线程c中加载的z
和x
的值分别为1和0,并不意味着线程d无法将y
读为1,并且y
的值为0。在这种情况下,x
的值为0。因此,这允许z
的值为0、1或2。