首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C# 執行緒同步機制全景圖:從 volatile 到 WaitHandle 的原理與選型指南

     編輯:關於C語言

前言

.NET 提供豐富的同步原語,各有適用場景與效能特性。本文系統整理 10 大同步機制的實作原理、適用條件與選型建議,協助開發者在正確性與效能間取得平衡。

一、輕量級使用者模式同步

機制原理適用場景注意事項
volatile禁止編譯器/CPU 將欄位快取至暫存器,強制從主記憶體讀寫單一變數的跨執行緒可見性(如旗標)非原子操作,無法解決複合動作競爭;多核下仍可能因快取一致性延遲失效
InterlockedCPU 專用指令鎖定記憶體匯流排,執行原子增減/交換/比較交換整數計數器、旗標原子翻轉、無鎖資料結構基石僅支援基本型別(int, long, float, double, IntPtr, Object)
lock / Monitor物件頭部 SyncBlockIndex 實作的輕量級互斥鎖,使用者模式自旋後進入核心等待大多數臨界區保護,程式碼簡潔、可重入進程內同步;避免鎖住公開物件或 this/typeof(T)

二、核心物件同步

機制原理適用場景注意事項
MutexWin32 Mutex Kernel Object 封裝,跨進程可見,具擁有權語意跨進程同步、單一應用程式實例檢查開銷大(使用者/核心模式切換);僅擁有者可 ReleaseMutex
Semaphore / SemaphoreSlim計數信號,WaitOne 遞減,Release 遞增;Slim 為輕量版資源池限流(連線數、並行度);Slim 適用高頻短暫等待無擁有權,任意執行緒可 Release;計數溢位拋例外
AutoResetEvent / ManualResetEventWin32 Event 封裝;Auto 釋放單一等待者,Manual 釋放所有執行緒間單次/多次通知協調核心物件,開銷較大;Slim 版本 (.NET 4+) 效能更好

三、進階與特殊用途

  • SpinLock / SpinWait:忙碌等待,適用極短臨界區(< 100 週期)且多核環境;單核下無意義。
  • ReaderWriterLockSlim:讀寫鎖,多讀單寫,適合「讀多寫少」資料結構(快取、字典)。
  • [Synchronization] / [MethodImpl(MethodImplOptions.Synchronized)]:屬性式同步,本質為 lock(this),不建議用於公開 API。
  • WaitHandle.WaitAll / WaitAny:多重等待,底層 WaitForMultipleObjects,WaitAll 需 COM 單一執行緒套房 (STA) 支援,效能較差,慎用。

四、選型決策樹

  1. 是否跨進程? → Mutex / 命名 Semaphore / EventWaitHandle
  2. 是否單一變數旗標/計數? → volatile (唯讀可見) / Interlocked (原子寫入)
  3. 是否讀多寫少? → ReaderWriterLockSlim
  4. 是否極短臨界區且高爭用? → SpinLock (結構體,需 try/finally 釋放)
  5. 一般臨界區保護? → lock (首選)
  6. 執行緒協調/通知? → AutoResetEvent / ManualResetEventSlim / SemaphoreSlim
  7. 非同步等待? → Task / SemaphoreSlim.WaitAsync / AsyncLock (社群套件)

五、最佳實務提醒

  • 鎖定專用私有物件:private readonly object _lock = new object();
  • 臨界區保持最小,避免在 lock 內呼叫外部虛擬方法/委派。
  • 避免巢狀鎖導致死結;若必要,固定獲取順序。
  • 使用 Monitor.TryEnter(timeout) 防止無限期阻塞。
  • 釋放 Mutex/Semaphore 時捕獲 ApplicationException (擁有權錯誤)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved