C# Interlocked 笔记
無鎖代碼下,在讀寫字段時使用內存屏障往往是不夠的。在 64 位字段上進行加、減操作需要使用Interlocked工具類這樣更加重型的方式。Interlocked也提供了Exchange和CompareExchange方法,后者能夠進行無鎖的讀-改-寫(read-modify-write)操作,只需要額外增加一點代碼。
如果一條語句在底層處理器上被當作一個獨立不可分割的指令,那么它本質上是原子的(atomic)。嚴格的原子性可以阻止任何搶占的可能。對于 32 位(或更低)的字段的簡單讀寫總是原子的。而操作 64 位字段僅在 64 位運行時環境下是原子的,并且結合了多個讀寫操作的語句必然不是原子的:
class Atomicity {static int _x, _y; static long _z; static void Test() { long myLocal; _x = 3; // 原子的 _z = 3; // 32位環境下不是原子的(_z 是64位的) myLocal = _z; // 32位環境下不是原子的(_z 是64位的) _y += _x; // 不是原子的 (結合了讀和寫操作) _x++; // 不是原子的 (結合了讀和寫操作) } }在 32 位環境下讀寫 64 位字段不是原子的,因為它需要兩條獨立的指令:每條用于對應的 32 位內存地址。所以,如果線程 X 在讀一個 64 位的值,同時線程 Y 更新它,那么線程 X 最終可能得到新舊兩個值按位組合后的結果(一個撕裂讀(torn read))。
編譯器實現x++這種一元運算,是通過先讀一個變量,然后計算,最后寫回去的方式。考慮如下類:
class ThreadUnsafe {static int _x = 1000; static void Go() { for (int i = 0; i < 100; i++) _x--; } }拋開內存屏障的事情,你可能會認為如果 10 個線程并發運行Go,最終_x會為0。然而,這并不一定,因為可能存在競態條件(race condition),在一個線程完成讀取x的當前值,減少值,把值寫回這個過程之間,被另一個線程搶占(導致一個過期的值被寫回)。
當然,可以通過用lock語句封裝非原子的操作來解決這些問題。實際上,鎖如果一致的使用,可以模擬原子性。然而,Interlocked類為這樣簡單的操作提供了一個更方便更快的方案:
class Program {static long _sum; static void Main() { // _sum // 簡單的自增/自減操作: Interlocked.Increment (ref _sum); // 1 Interlocked.Decrement (ref _sum); // 0 // 加/減一個值: Interlocked.Add (ref _sum, 3); // 3 // 讀取64位字段: Console.WriteLine (Interlocked.Read (ref _sum)); // 3 // 讀取當前值并且寫64位字段 // (打印 "3",并且將 _sum 更新為 10 ) Console.WriteLine (Interlocked.Exchange (ref _sum, 10)); // 10 // 僅當字段的當前值匹配特定的值(10)時才更新它: Console.WriteLine (Interlocked.CompareExchange (ref _sum, 123, 10); // 123 } }Interlocked上的所有方法都使用全柵欄。因此,通過Interlocked訪問字段不需要額外的柵欄,除非它們在程序其它地方沒有通過Interlocked或lock來訪問。
Interlocked的數學運算操作僅限于Increment、Decrement以及Add。如果你希望進行乘法或其它計算,在無鎖方式下可以使用CompareExchange方法(通常與自旋等待一起使用)。我們會在并行編程中提供一個例子。
Interlocked類通過將原子性的需求傳達給操作系統和虛擬機來進行實現其功能。
Interlocked類的方法通常產生 10ns 的開銷,是無競爭鎖的一半。此外,因為它們不會導致阻塞,所以不會帶來上下文切換的開銷。然而,如果在循環中多次迭代使用Interlocked,就可能比在循環外使用一個鎖的效率低(不過Interlocked可以實現更高的并發度)。
轉載于:https://www.cnblogs.com/kzwrcom/p/5392141.html
總結
以上是生活随笔為你收集整理的C# Interlocked 笔记的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 数学老师必备工具,你的最爱!
- 下一篇: 算法(一)