全局排序和每个原子变量排序有何不同?

时间:2016-01-05 19:26:15

标签: c++ c++11 memory-model

我试图理解memory_order_seq_cst和memory_order_acq_rel之间的区别。关于SO的一些帖子已经涵盖了这个问题,但是,我不理解他们的答案。

This post

  

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.

我的问题是:

  1. 不要(!x)和while(!y)保证if(y)或if(x)返回true,即使我们使用每个原子变量排序?
  2. 这个例子如何解释memory_order_acq_rel和memory_order_seq_cst之间的区别?
  3. 任何人都可以提供一个使用内存栅栏的例子来说明每个原子变量排序和全局排序之间的区别吗?

1 个答案:

答案 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的排序要求将对xy的所有加载/存储操作强制执行总排序,这意味着x=true;发生在y=true或{{1之前}}发生在y=true之前。因此x=true的可能值为1或2。 而对于memory_order_acq_rel,如果线程c中加载的zx的值分别为1和0,并不意味着线程d无法将y读为1,并且y的值为0。在这种情况下,x的值为0。因此,这允许z的值为0、1或2。