2013-11-03 78 views
2

我打算在升压原子的文档和我碰到下面的例子就是:需要帮助理解Boost.Atomic内存模型`memory_order_release`例

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如何发生冲突,我将不胜感激。

回答

2

的定义是指在没有A中的存储器操作的可在商店之后(在问题释放的定义)被重新排序以a。并且B或C中的操作都不能在其他线程中的a的负载之前(在问题中定义获得)。

现在,示例假设没有其他代码在a上运行,或者至少写入a。如果执行B,则意味着在发生tmp负载时a的值为1。对于a具有值1,则必须先执行fetch_addfetch_addload同步),这意味着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碰到相同的变量,并且至少有一个写入它,那么就有竞争条件。

+0

感谢您的答复。这解释了很多。还有一个问题,在你的帖子开头你说过:“这些定义意味着在存储之后,A中的所有内存操作都不能重新排序。你能解释一下在这里重新排序意味着什么“非内存操作可以重新排序”是什么意思? – MistyD

+0

@MistyD:如果A的最后一行包含对变量'b'的更新,'memory_order_release'确保编译器和CPU都不会在更新到'a'之后将写入重新排序到'b'。没有这个保证,如果B访问'b',可能会出现竞争条件 –