3.6 程序間的溝通 (Process Communication)
又稱為 inter-process communication IPC
方法有兩種:
- Shared Memory
- Message Passing
圖:
目錄
- Shared Memory
- Message Passing
Shared Memory 分享記憶體
Def: 指多個 process 藉由共用相同的 memory space 達到行程間溝通之效 (Multiprocessor)
問題:Race Condition 競爭情況
Def: 相同的運作. 因執行順序不同, 造成處理的結果不同謂之
解決:Critical Section 臨界區間
Def: 為一程式片段, 用來提供多 process 共用一 memory space 時的存取控管機制 => 避免 race conditional
Critical Section Design
格式:
良好的 C.S Design 需滿足:
- Mutual exclusion (互斥):指同一時間只允許一個 process 進入 C.S.
- Progress (可進行性):不想進 C.S. 的 process, 不能影響其他欲進入 C.S. 之 process
- 若有多個 process 欲進入 C.S., 則挑選的時間是有限的 => 避免 deadlock
- Bounded waiting (有限性等待):指 n 個 process 存在於進入 C.S., 最多只需 wait n-1 次 => 公平, No starvation
C.S. Design 目錄
- algo
- 2 process => 3 algos (turn, flag)
- 2 process => 1 algos (turn + flag)
- Semaphore
- Binary
- Counting
2 個 process 的 C.S. Design
algorithm1:
- 資料結構 (宣告變數):
var turn: integer (0~1);
- Pi 之程式片段:
- 分析:
- 滿足 mutual exclusion (互斥)
說明:
當 Pi, Pj 皆欲進入 C.S., 又 turn 不會同時為 i, j (因為 i 不等於 j), 故只能一個 process 進入 C.S. - 不滿足 progress (可進行性)
說明:
當 Pj 於 R.S. 中 (因為 j 就是不想上廁所), 但turn = j
, 此時若 Pi 想進入 C.S., 將被卡在 while loop 中無法進入 (因為違反 progress)
- 滿足 mutual exclusion (互斥)
algorithm2:
-
資料結構:
var flag [0...1] of Boolean;
-
Pi 之程式片段:
-
分析:
- 滿足 mutual exclusion (互斥)
說明:
若欲使 Pi, Pj 同時進入 C.S., 則flag[i] = flag[j] = false
, 又當欲進入 C.S. 一開始 flag, 會改為 true, 故上述情況不可能存在 - 不滿足 progress (可進行性)
說明:
當 Pi, Pj 皆欲進入 C.S., 則flag[i] = flag[j] = true
, 此時 2 者皆會卡在 while loop 中 => deadlock, 故違反 progress
- 滿足 mutual exclusion (互斥)
-
中山
1 | flag[i] = true; |
若交換上述兩行程式, 會發生什麼事?
Ans: 違反互斥性, 變成先問對方在舉手
algorithm3:
-
資料結構:
-
Pi 之程式片段:
-
分析:
- 滿足 mutual exclusion (互斥)
說明:
當 2 process 皆欲進入 C.S., 則flag[i] = flag[j] = true
, 但 turn 不會同時為 i, j (因為 i 不等於 j), 故只有一 process 可進入 C.S. - 滿足 progress (可進行性)
說明:- 當 Pj 不想進入 C.S., 又
turn = j
, 且此時flag[j] = false
, 故當 Pi 想進入, 可以順利通過 while loop - 當 2 process 皆欲進入 C.S., 此時視 turn 的值為 i 或 j, 指向者可進入 C.S., 所以 No deadlock
- 當 Pj 不想進入 C.S., 又
- 滿足 Bounded Waiting (有限性等待)
說明:
當 Pi, Pj 皆欲進入 C.S., 而turn = j
時, 則 Pj 可進入, 若 Pj 離開後立即再度欲進入 C.S., 則:
flag[j] = true;
turn = i
因為turn = i
, 故下次必由 Pj 進入 C.S. 中
- 滿足 mutual exclusion (互斥)
多 process 的 C.S. Design => Bakery’s algorithm
- 資料結構:
1 | var choosing: Array[0....n-1] of Boolean; |
-
數字假設:
(a, b) < (c, d)
, ifa < c
ora = c
且b < d
Max(X0...Xn-1)
=> 取 X0 ~ Xn-1 中最大值
-
Pi 之程式片段:
Semaphore (號誌) (可有互斥的效果)
- Def: 為解決同步問題的一種機制, 本身為一整數型別 (通常初始為 1), 會提供 2 個 atomically execution (不可分割, 指過程中不能被中斷) 的運作
- signal
- wait
- 圖:
- Note:
Semaphore 初始值為 1 時, 則狀態永遠為 0 或 1, 故 Pj 謂之 Binary Semaphore (二元號誌)
Counting Semaphore (計數號誌)
Def: 有別於 Binary Semaphore, 於 counting semaphore 之中, 值可能為 1, 0, -1, -2…-n, 若值為 -n, 代表有 n 個 process 卡在 wait 之中
=> 製作方式:
- 用 Block, wakeup 製作
- 用 Binary Semaphore 製作
<法一>:用 Block, wakeup 及 Queue 製作
- 作法:將 Semaphore 定義成一 Record (紀錄) (like class)
1 | type countingSemaphore: record |
<法二>:用 Binary Semaphore 製作出 counting semaphore
- 資料結構:
1 | var c: integer; initial = 1 // 計數器, like value, c 當 signal & wait |
Compare
Compare | busy waiting (spinlock 盤旋鎖) 製作 counting semaphore (簡單的會使用) | Block, wakeup 製作 (複雜的通常用) |
---|---|---|
優點 | wait 時不會有 context switching, 若為片刻等待, 適用 | wait 時不會用至 CPU |
缺點 | 在 waiting 過程中, 會不斷的耗用 CPU 的資源, 所以浪費 CPU | 需 context switching |