在 Linux 核心開發中,並發控制是核心議題。理解臨界區、競爭狀態、同步原語與死鎖預防,是編寫高效、穩定核心代碼的基石。
死鎖分為自死鎖(同一任務重複請求不可重入鎖)與 ABBA 死鎖(任務 A 持有鎖 1 請求鎖 2,任務 B 持有鎖 2 請求鎖 1)。產生死鎖的四個必要條件(Coffman 條件):
避免方法:破壞任一條件即可。核心常用策略包括:鎖排序(統一獲取順序,破壞循環等待)、嘗試鎖(mutex_trylock 失敗即放棄,破壞請求並保持)、可搶佔鎖(RT 內核中鎖可被高優先級任務搶佔)以及鎖分級(細化鎖粒度,減少持有時間)。
Linux 核心屬於搶佔式多任務系統,並發來源包含:
CONFIG_PREEMPT 後,核心態任務可被高優先級任務搶佔。Linux 信號量是睡眠鎖,適合長時間持有的場景(如文件系統操作)。源自 Dijkstra 1968 年經典 P/V 操作,對應核心 down()(P,獲取/減 1)與 up()(V,釋放/加 1)。
down():若計數器 > 0,遞減並繼續;否則將當前任務加入等待隊列並睡眠(TASK_UNINTERRUPTIBLE 或 TASK_INTERRUPTIBLE)。up():遞增計數器,若等待隊列非空,喚醒一個任務(通常是 FIFO 順序)。核心提供 struct semaphore、init_MUTEX()、down_interruptible()(可被信號打斷)等介面。注意:中斷上下文不可使用睡眠鎖,必須用自旋鎖或 local_bh_disable() 等機制。