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

淺談 .NET 多執行緒與平行運算(十三):CLR via C# 閱讀筆記——執行緒同步核心觀念與效能測試

     編輯:關於ASP.NET

本文整理自《CLR via C# 第三版》關於執行緒同步的核心觀念、兩種同步結構(使用者模式/核心模式)效能對比,並附上作者實測程式碼與結果分析。

執行緒同步三大代價

  1. 識別困難:需找出所有可能被多執行緒存取的資源,無法驗證同步是否正確/完整/過度。
  2. 效能損耗:短暫操作加上鎖申請/釋放,效能可能下降一個數量級。
  3. 增加執行緒建立與上下文切換:阻塞導致排程器建立更多執行緒維持吞吐量。

何時「不需要」同步?

  • 唯讀資源:多執行緒同時讀取不可變物件(如 string、readonly 欄位)無需同步。
  • 值型別或不可變型別:操作會建立新實例,非共享狀態。
  • 非共享範圍:ThreadLocal、方法區域變數、非 static 欄位(每個實例獨立)。

FCL 執行緒安全承諾

  • 所有 靜態方法 保證執行緒安全。
  • 實例方法 不保證(效能考量),需自行同步。
  • 自訂類庫建議遵循相同標準:靜態安全、實例不保證。

兩種同步結構對比

效能測試程式碼與結果

class Program
{
    static void Main()
    {
        const int Iterations = 5_000_000;
        int x = 0;
        var sw = Stopwatch.StartNew();

        // 使用者模式:SimpleSpinLock (Interlocked.Exchange)
        var ssl = new SimpleSpinLock();
        for (int i = 0; i < Iterations; i++) { ssl.Enter(); x++; ssl.Leave(); }
        Console.WriteLine($"SimpleSpinLock: {sw.ElapsedMilliseconds:N0} ms");

        // 核心模式:SimpleWaitLock (AutoResetEvent)
        using (var swl = new SimpleWaitLock())
        {
            sw.Restart();
            for (int i = 0; i < Iterations; i++) { swl.Enter(); x++; swl.Leave(); }
            Console.WriteLine($"SimpleWaitLock: {sw.ElapsedMilliseconds:N0} ms");
        }
    }
}

struct SimpleSpinLock
{
    private int _resourceInUse;
    public void Enter() { while (Interlocked.Exchange(ref _resourceInUse, 1) != 0) { } }
    public void Leave() { Thread.VolatileWrite(ref _resourceInUse, 0); }
}

class SimpleWaitLock : IDisposable
{
    private readonly AutoResetEvent _free = new AutoResetEvent(true);
    public void Enter() => _free.WaitOne();
    public void Leave() => _free.Set();
    public void Dispose() => _free.Close();
}

測試結果解讀

  • 無競爭時:SpinLock 極快(僅數十 ns),WaitLock 需微秒級核心轉換。
  • 高競爭時:SpinLock 空轉燒 CPU,WaitLock 釋放 CPU 更有利系統整體吞吐。
  • 實務建議:短關鍵區、低競爭用 SpinLock/Interlocked;長關鍵區、高競爭、需逾時/跨進程用核心物件。

Monitor 與 lock 關鍵字

C# lock(obj) 編譯為 Monitor.Enter/Exit,屬核心模式混合實作:先嘗試使用者模式自旋,失敗再進核心等待,兼顧效能與彈性,是最常用的同步原語。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
特性使用者模式核心模式
代表SpinLock, InterlockedMutex, Semaphore, AutoResetEvent, Monitor
支援層級硬體指令 (CAS)作業系統核心物件
速度極快 (無模式切換)較慢 (Ring 3 → Ring 0)
阻塞行為忙碌等待 (消耗 CPU)釋放 CPU,進入等待狀態
功能彈性僅支援互斥支援逾時、等待多物件、跨進程同步