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

信號量原理與 P/V 操作詳解:進程同步互斥的基石

     編輯:關於C語言

信號量的誕生與本質

1965 年,Dijkstra 引入信號量解決並發程式設計中的同步與互斥問題。其核心定義:

信號量是一個非負整數,僅支援兩種 原子操作:P (wait) 與 V (signal)

原子操作:不可分割的執行單元

原子操作在執行過程中 不能被中斷。生活類比:

  • ❌ 寫代碼時收到郵件通知 → vim 被中斷 → 非原子
  • ✅ CPU 執行單條指令 → 不可中斷 → 原子

P 操作 (等待信號 / wait / down)

P(sem):
    if sem > 0:
        sem -= 1
    else:
        block(current_process)  // 掛起進程

語義:申請資源,資源不足則等待

V 操作 (發送信號 / signal / up)

V(sem):
    if 有進程等待 sem:
        wakeup(one_waiting_process)
    else:
        sem += 1

語義:釋放資源,喚醒等待者

偽代碼:臨界區保護模式

// 非臨界區
nocritical_code();

P(sem);           // 進入臨界區
{
    critical_code();  // 共享資源存取
    do_something();
}
V(sem);           // 離開臨界區

nocritical_code();

執行場景推演

初始條件:sem = 1

  1. 進程 A 執行 P(sem) → sem 變 0 → 進入臨界區
  2. 進程 B 執行 P(sem) → sem = 0 → 被掛起
  3. 進程 A 執行 V(sem) → 發現 B 等待 → 喚醒 B → sem 仍為 0
  4. 進程 B 被喚醒 → 進入臨界區

結果:同一時間僅有一個進程在臨界區 → 實現互斥

信號量分類與應用

類型初值用途範例
二元信號量1互斥鎖保護共享變數、檔案、硬體裝置
計數信號量N (>0)資源計數/同步生產者-消費者緩衝區、連線池
同步信號量0事件通知執行緒完成通知、非同步 I/O 回調

經典同步模式

生產者-消費者 (雙緩衝)

sem_t mutex = 1;      // 互斥存取緩衝區
sem_t empty = N;      // 空位數量
sem_t full = 0;       // 滿位數量

// 生產者
P(empty); P(mutex);
put_item();
V(mutex); V(full);

// 消費者
P(full); P(mutex);
take_item();
V(mutex); V(empty);

從理論到實作:下一步

理解 P/V 原理後,下一階段將學習:

  • System V 信號量 API (semget/semop/semctl)
  • POSIX 信號量 (sem_init/sem_wait/sem_post)
  • 實際程式碼範例:保護共享記憶體、實現生產者消費者
  • 死鎖預防:資源有序申請、超時機制、死鎖檢測

「信號量是並發程式設計的瑞士刀——簡單強大,但使用不當同樣危險。」

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