需要帮助了解Boost.Atomic Memory Model`memory_order_release`示例

时间:2013-11-03 02:47:35

标签: c++ boost atomic memory-model

我正在修改Atomic文档,我遇到了以下示例:

atomic<int> a(0);

thread1:
  ... /* A */
  a.fetch_add(1, memory_order_release);

thread2:
  int tmp = a.load(memory_order_acquire);
  if (tmp == 1) 
  {
    ... /* B */
  } 
  else 
  {
    ... /* C */
  }

现在我对memory_order_release和memory_order_acquire仍感到有点困惑。文档将它们描述为:

memory_order_release

  

执行释放操作。非正式地说,阻止所有前面的   记忆操作要经过这一点重新排序。

memory_order_acquire

  

执行获取操作。非正式地说,阻止成功   在此之前要重新排序的内存操作。

即使有这些例子,我仍然有点困惑。如果有人能够解释上述定义的含义以及A和C如何发生冲突,我将不胜感激?

1 个答案:

答案 0 :(得分:2)

这些定义意味着在存储到a(问题中发布的定义)之后,A中的任何内存操作都不能重新排序。并且B或C中的任何操作都不能在另一个线程中a的加载之前(问题中获取的定义)。

现在,该示例假设没有其他代码在a上运行,或者至少写入a。如果执行B,则意味着a在加载tmp时发生的值为1。要使a具有值1,必须在fetch_addfetch_add同步之前执行load,这意味着A中的代码已完成执行。如果命中该特定代码路径,则操作的顺序为:

A
a.fetch_add(1,memory_order_release);
int tmp = a.load(memory_order_acquire);
B

现在其他选项是当load发生时,值仍为0.这意味着第一个线程没有执行fetch_add,但不能保证它在哪里可能正在执行。当线程2执行C时,A可能仍在执行(或者它甚至可能尚未启动,或者它可能已经完成)。

如果A和B都访问同一个变量,则没有冲突,因为原子保证B只能在A完成后才能执行。另一方面,C没有给出保证,所以如果A和C触摸相同的变量并且至少有一个变量写入,那么就存在竞争条件。