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

C 語言進程間通信深度解析(一):臨界資源與同步機制

     編輯:關於C語言

什麼是臨界資源?

在作業系統與並發程式設計中,臨界資源 是指:

一種稀缺資源,可被多個進程共享使用,但同一時刻只允許一個進程存取。

典型例子:

  • 印表機:同時列印會導致內容交錯混亂
  • 共享檔案:多進程同時寫入會造成資料損毀
  • 共享記憶體區域:並發讀寫需同步保護
  • 硬體裝置暫存器:同時存取會導致狀態錯誤

為什麼需要臨界資源管理?

進程間通信(IPC)需解決三大核心問題:

  1. 資料傳遞: 進程如何交換資訊(訊號、管道、訊息佇列等)
  2. 資源共享: 多進程如何安全存取臨界資源(互斥鎖、信號量、監視器)
  3. 執行協調: 進程如何有序推進任務(條件變數、屏障、事件)

前幾章已介紹訊號與管道解決「資料傳遞」問題,本章聚焦「資源共享」——即臨界資源的保護機制。

臨界區與競態條件

// 經典競態條件範例:銀行轉帳
// 進程 A:讀取餘額 1000 → 扣除 100 → 寫回 900
// 進程 B:讀取餘額 1000 → 扣除 200 → 寫回 800
// 最終結果:800(錯誤!正確應為 700)

臨界區 是進程中存取臨界資源的程式碼片段。若多進程同時進入各自的臨界區操作同一資源,即發生競態條件。

互斥的三種經典解法

1. Peterson 演算法(軟體層級,教學用)

int turn;           // 輪到誰
int flag[2] = {0};  // 想進入旗標

// 進程 i 進入臨界區
flag[i] = 1;
turn = j;
while (flag[j] && turn == j);  // 忙等待
// 臨界區
flag[i] = 0;  // 離開

2. 硬體指令支援(Test-and-Set, Compare-and-Swap)

// 原子操作範例(偽代碼)
boolean test_and_set(boolean *lock) {
    boolean old = *lock;
    *lock = true;
    return old;  // 原子執行,不可中斷
}

// 自旋鎖實現
while (test_and_set(&lock));  // 獲取鎖
// 臨界區
lock = false;  // 釋放鎖

3. 作業系統核心同步原語(實務標準)

  • 互斥鎖: 只有擁有者能解鎖,支援優先級繼承
  • 信號量: 計數器機制,可實現多資源同步
  • 監視器/條件變數: 高層抽象,編譯器/執行期支援

檔案作為臨界資源的實例

文章提到的 vim 與 gedit 同時編輯 test.c:

  • 現代編輯器通常採用檔案鎖定或樂觀鎖機制
  • 第二個開啟者會收到警告:「檔案已被修改,是否重新載入?」
  • 底層依賴 fcntl(F_SETLK)、flock() 或 lockf() 系統呼叫

下一步:System V IPC 同步機制

文章預告將介紹兩種核心 IPC 同步物件:

  1. 共享記憶體 + 信號量: 高效資料交換 + 存取同步
  2. 訊息佇列: 內核維護的訊息緩衝區,天然具備同步特性

這兩者都是 System V IPC 體系的核心組件,廣泛應用於 Unix/Linux 系統程式開發。

總結

臨界資源是並發程式設計的核心挑戰。理解競態條件、臨界區概念,掌握從軟體演算法到硬體指令再到 OS 核心原語的互斥演進脈絡,是寫出正確、高效並發程式的基石。下一章將深入 System V IPC 架構與具體 API 實戰。

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