2013-02-27 87 views
3

我想對共享變量執行兩個操作。我需要保證它可以以原子方式完成。可有一個人幫我澄清一下,如果下面的做法是正確的:在共享變量上執行多個原子操作

#include <atomic> 
std::atomic<int> index; 

void function() 
{ 
    // I need the variable index to be incremented but bound in the 
    // range of [0,9]. 
    int loc_indx = index.load(std::memory_order_acquire); 
    index.store((loc_indx+1)%10 , std::memory_order_release); 
} 

根據我的理解,索引存儲操作和索引負荷運行要一起發生。一些專家可以在這裏澄清,如果上面的代碼將等同於以下僞代碼:的Visual Studio 2012的

ATOMIC 
{ 
    index = (index+1)%10; 
} 

我一直在C與原子包工作++部分或/和boost ::原子組成部分1.53。

+0

所有的線程都調用'function()'來訪問'index'嗎?或者,他們是否可以自由訪問'索引',但他們想要? – 2013-02-27 18:42:56

+0

增量只能通過所有線程調用'function()'完成。是的,有更多的線程同時訪問'function()'。 – Goutham 2013-02-27 18:51:12

回答

4

原子的整體目的是提高性能與鎖相比。

代碼中沒有鎖。 memory_order枚舉只是爲了確保編譯器不重新排序代碼(也不要讓CPU重新排序)。這意味着其他線程修改loadstore之間的值的可能性很小。如果存儲的值必須取決於先前的值,則在兩者之間完成的計算將被浪費並需要重做。這樣做比鎖更有效率,因爲併發修改實際發生的可能性很小,並且計算起來既便宜又簡單。

當您知道之前的值時存儲,否則重新計算並重試。類似:

int loc_index = index.load(std::memory_order_acquire); 
int desired = (loc_index+1)%10; 

while (!index.compare_exchange_strong(loc_index, desired)) 
{ 
    desired = (loc_index+1)%10; 
} 

compare_exchange_strong是原子操作,其比較存儲於indexloc_index值;如果它們相同,則將desired存儲到index;如果它們不相等,則將index的值複製到loc_index中。這有助於確保存儲在index中的下一個 值是正確的。

+0

你缺少'('在第4行(從1 :-)開始)。 – 2013-02-27 18:59:00

+0

哦。謝謝。固定。 :) – 2013-02-27 19:00:32

+1

如果你可以添加一些解釋,這將是非常有益的。 – Goutham 2013-02-27 19:02:16