2012-04-13 40 views
5

int val = memLoc[index++];我可以使以下代碼鎖定爲空白/原子嗎?

或更好,但

int val = memLoc[index++ & 0xFF];

試圖做從那裏每次調用獲取下一個值共享的環形緩衝區讀取線程 - 我很想它是無鎖,如果在所有可能的,因爲它發生在TON。不允許Boost/C++ 11 :(

+3

您可能有興趣閱讀[本文](http://www.codeproject.com/Articles/43510/Lock-Free-Single-Producer-Single-Consumer-Circular)。 – 2012-04-13 14:36:55

+3

沒有C++ 11意味着你需要一個預標準的解決方案。如果Boost是不可接受的,那麼所有其他圖書館(擁有更嚴格的許可條款)也可能出來,所以你不能得到任何便攜。那麼,你需要這個操作系統? – MSalters 2012-04-13 15:15:15

+0

什麼類型是'memLoc'?它是一個指向(int)的指針(或數組)嗎? – 2012-04-13 15:20:43

回答

6

這裏需要同步的唯一操作是index值的增量。由於這只是一個數值,因此可以不通過原子增量使用鎖定。你列出的操作的剩下的只是讀取的共享位置,並不需要同步。

在Win32製作同步與InterlockedIncrement功能所做的增量

int oldValue = InterlockedIncrement(&index); 
int val = memLoc[oldValue & 0xFF]; 

有各種花樣增量功能在Linux上可用關於你需要增加在原子操作讀回指數在此計算器線程的選項

+2

在C++ 11中,有'std :: atomic_fetch_add'應該可以做到這一點。 – 2012-04-13 14:57:01

+0

有沒有寫'int'的任何體系結構都不是原子的(你必須同步讀取的元素)? – 2012-04-13 15:16:58

+0

@MarkB問題不僅僅是元素的原子寫入,它是原子寫入+讀取舊值+確保它在所有處理器中都可見。通常你需要一個特別的指導。看着我的回答,我在幾個地方誤用了原子。去清理那個。 – JaredPar 2012-04-13 15:19:29

1

d討論。不幸的是,++運算符不保證任何原子性。

大多數處理器都有某種可以使用的提取 - 增量 - 存儲指令。您可以插入內聯程序集來執行此操作。 http://en.wikipedia.org/wiki/Fetch-and-add

如果你在Windows上運行,微軟提供了一個API來訪問此:http://msdn.microsoft.com/en-us/library/windows/desktop/ms684122(v=vs.85).aspx

如果你在其他操作系統,有可能類似的功能。不過,無論如何,您需要操作系統或更低級別的訪問才能獲得原子訪存 - 增量存儲。

相關問題