2013-11-03 59 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',可能會出現競爭條件 –