Windows Programming/Interlocked變量訪問

Interlocked變量訪問是Windows API提供的一種對DWORD或指針類型的變量原子訪問機制。[1]

對於32位地址對齊的變量,在32位CPU上的讀寫操作是原子的,即變量不會只被修改一部分。但訪問不能保證同步。如果兩個線程同時讀寫一個變量,不能保證是否有一個線程讀操作在另一個線程的寫操作之前。如果是加一操作,兩個線程的執行結果可能是該變量只被加了1而不是被加了2。上述情況對64位CPU上的64位對齊變量也適用。64位系統的對應API函數,使用「64」後綴。

底層實現

編輯

x86平台使用LOCK prefix指令。ia64與x64直接支持load-modify-store操作。

其它平台使用Load-link/store-conditional,先通過load-link讀值,執行期望的計算,在試圖通過store-conditional保存值。如果store-conditional失敗,重啟這些操作。實際上CPU會監視整條cache line。硬件中斷會導致store-conditional失敗。[2]

函數列表

編輯

原子加減1操作

編輯

InterlockedIncrement與InterlockedDecrement

提供了加1或者減1原子操作。 執行原子加1操作,參數Addend的值會被加1,返回值為原始操作加1後的當前值。

比較並交換操作(Compare and Swap, CAS)

編輯

InterlockedCompareExchange, InterlockedCompare64Exchange128與InterlockedCompareExchangePointer函數讀出其原值,原值與比較值如果相等則賦予新值的原子操作。

InterlockedCompareExchange()帶有全局的內存柵障,不帶全局內存柵障的對應操作為InterlockedCompareExchangeAcquire()與InterlockedCompareExchangeRelease()


原子寫操作

編輯

InterlockedExchange與InterlockedExchangePointer函數提供了對long與指針變量讀出其原值,賦予新值的原子操作。InterlockedExchangeAdd與InterlockedExchangeSubtract函數提供了對long型變量讀出其原值,加上/減少一個增量值的原子操作。

原子加法、或運算、異或運算

編輯

InterlockedAnd, InterlockedOr與InterlockedXor提供了與、或、異或的原子操作

InterlockedAdd返回了變量被原子增加一個值的結果。

原子比特位測試設置

編輯

InterlockedBitTestAndSet,InterlockedBitTestAndReset與InterlockedBitTestAndComplement函數提供讀出變量指定比特位的原值,並置位/復位/翻轉該比特位的值的原子操作。

參考文獻

編輯
  1. Raymond Chen: Interlocked operations don’t solve everything in 「old newthing」
  2. Raymond Chen: How does InterlockedIncrement work internally? in 「old newthing」