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

C# 避免線程死鎖:鎖順序一致性與 lock 機制

     編輯:關於C語言

死鎖核心原因:多線程以不同順序獲取同一組鎖。轉帳案例完美演示經典死鎖場景。

死鎖代碼示例

public void Transfer(Account from, Account to, decimal amount) {
    Monitor.Enter(from); // 鎖定賬戶 A
    Monitor.Enter(to);   // 鎖定賬戶 B
    // 業務邏輯...
    Monitor.Exit(from);
    Monitor.Exit(to);
}

// 線程 1:Transfer(A, B) → 鎖 A → 鎖 B
// 線程 2:Transfer(B, A) → 鎖 B → 鎖 A
// 經典死鎖形成

解決方案:統一鎖順序

public void Transfer(Account from, Account to, decimal amount) {
    // 根據不可變標識(如 ID)排序,保證全局一致獲取順序
    var first = from.Id < to.Id ? from : to;
    var second = from.Id < to.Id ? to : from;

    lock (first) {
        lock (second) {
            // 安全轉帳邏輯
        }
    }
}

關鍵原則

  • 鎖順序一致性:所有代碼路徑按相同順序獲取多把鎖
  • 縮小鎖範圍:`lock` 塊內盡量少執行耗時操作
  • 避免巢狀鎖:重構代碼減少多鎖依賴
  • 使用 `lock(this)` 謹慎:公開實例可能被外部代碼鎖定,導致不可控死鎖

進階工具

  • `Monitor.TryEnter`:帶超時嘗試獲取鎖
  • `SemaphoreSlim` / `ReaderWriterLockSlim`:更精細的同步控制
  • 死鎖檢測:Visual Studio 並行堆疊、dotMemory 分析
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved