2014-01-21 63 views
2

比方說,我有1個計數器從值2開始,一些非原子布爾變量和4個線程。C++獲取/釋放排序

//Initialization (happens before any thread execute). 
std::atomic<int> count = ATOMIC_VAR_INIT(2); 
bool someBoolean = false; 

線程1:

count.fetch_sub(1, std::memory_order_release); 

線程2:

someBoolean = true; 
count.fetch_sub(1, std::memory_order_release); 

線程3:

while(count.load(std::memory_order_acquire) != 0); 
//Now, we're out of the while loop... 
assert(someBoolean); 

線程4:

while(std::atomic_thread_fence(std::memory_order_acquire), 
     count.load(std::memory_order_relaxed) != 0); 
//Now, we're out of the while loop... 
assert(someBoolean); 

線程3或線程4的斷言可能會觸發嗎?

回答

3

線程4可能會觸發斷言,因爲您使用load操作和內存籬笆的順序不正確。您必須首先將loadcount變量,然後放置內存獲取圍欄。
在一般情況下,您必須在寫入同步標誌之前放置發佈圍欄,並在讀取後放置獲取圍欄

你可以找到在這個職位從大傑夫Preshing的博客上詳細解釋,並獲得/釋放內存圍欄的例子: http://preshing.com/20130922/acquire-and-release-fences/

線程3(和固定的函數調用命令後線程4),將不會觸發一個斷言,因爲線程之間的關係的同步正確建立。