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

編程好習慣:縮小鎖粒度提升併發效能

     編輯:關於C語言

鎖粒度的兩個維度

多任務環境中,為避免競爭條件必須使用鎖(Mutex/關中斷)。良好習慣是讓上鎖範圍盡可能小,包含兩個維度:

  • 時間維度:持有鎖的程式碼路徑長度
  • 資源維度:一把鎖保護的資源範圍

時間維度:縮小關鍵區長度

反例:timer_init() 在檢查標記、初始化多個欄位、設定名稱等完整流程中持有鎖(第 123–145 行)。

優化:僅在「檢查標記 + 設定標記」這段不可分割的原子操作中持有鎖(第 123–130 行),其餘初始化邏輯移至解鎖後:

timer_lock();
if (TIMER_MARK == _handler->mark_) { timer_unlock(); return ERROR; }
_handler->mark_ = TIMER_MARK;  // 佔位,防止重入
timer_unlock();
// ... 耗時的欄位初始化、字串複製等 ...

效益:縮短鎖持有時間,減少其他任務阻塞機率,提升系統即時性與吞吐量。

資源維度:專鎖專用

若模組存取獨立資源 A、B,部分函式只用 A,部分只用 B,部分兩者都用。應設計兩把獨立鎖:

  • lock_A() 保護資源 A
  • lock_B() 保護資源 B
  • 需同時存取 A、B 時,按固定順序(如先 A 後 B)雙重加鎖,避免死結

錯誤做法:單一大鎖保護所有資源,導致只存取 A 的任務也被存取 B 的任務阻塞。

資源維度細分最終服務於時間維度:縮小單一資源的鎖爭用範圍,降低平均等待時間。

實務檢查清單

  1. 關鍵區是否包含 I/O、記憶體配置、日誌輸出等慢速操作?→ 移出
  2. 是否在迴圈內持有鎖?→ 縮小至單次迭代或移出
  3. 多資源是否共用一把鎖?→ 拆分為細粒度鎖
  4. 鎖順序是否固定?→ 文件化並強制執行

核心原則

「鎖越粗,併發度越低;鎖越細,複雜度越高。在正確性前提下,找到平衡點。」

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved