Professional Documents
Culture Documents
Ch6 Process Sychronization - Dox
Ch6 Process Sychronization - Dox
○
2 Message Passing
宣告共享變數 :
turn:整數,存放的値為 i 或 j,誰擁有此值誰就有資格進入。
flag[i]:布林陣列,表示 i 想不想進去。
2. 正確版 algo 2
Repeat
waiting[i] = true; //有意進 C.S,等待中
key = true;
while(waiting[i] && key) do //key = false,離開 while
//waiting 被別人改成 false,離開 while
key = Test_and_Set(Lock);
waiting[i] = false; //可以進入,不用等了 (拿掉會 Deadlock) 違反 Progress(i)(ii)
C.S.
j = (i+1) % n; //j 先從 i 的下一個 process 開始
while(j!=i && not waiting[j]) do //找下一個想進 C.S 的 Pj
j = (j+1) % n;
if(j == i) then Lock = False; //若成立,表示現在沒人想進 C.S
else waiting[j] = false; //讓 Pj 進入 C.S
R.S.
until false
Swap
Repeat
違反 Bounded waiting:未規範 order 使得次序以亂數決定。
key = true;
repeat
☆ 修改方法:將 Test-and-Set 中修改 1 行
SWAP(Lock, key);
until key = False;
while(waiting[i] && key) do
C.S.
key = Test_and_Set(Lock);
Lock = False;
Swap(key,Lock)
R.S.
Until false
Semaphore
○
1 wait(S) = P(S):while(S <= 0)do no-op; //S 大於 0 就給過,但 S 要減 1
S = S – 1;
○
2 Signal(S) = V(S):S = S + 1;
著名同步問題
1. Producer-Consumer Problem
N 個 buffers,Producer 製造項目,Consumer 消耗項目。
(i) 不完善的實現
宣告共享變數:
int itemCount = 0;
(1) R/W 互斥
(一)必須滿足的基本同步條件 { (RR 不需互斥)
(2) W/W 互斥
(二)可分 2 種
do{//writer do{//Reader
wait(wrt); wait(mutex); 若成立代表你是第 1 個 reader
// writing is performed readcount++;
signal(wrt); if(readercount == 1) wait(wrt); //看是否可以通過 r/w 互斥,
}while(true); signal(mutex) 若可通過,也順便卡住 writer
// reading is performed
wait(mutex);
readcount--;
if(readcount == 0) signal(wrt); //沒有 reader,可放 writer
signal(mutex);
}while(true)
Semaphore x = 1
Semaphore y = 1
Semaphore z = 1 //reader 入口區管制
Semaphore wsem = 1 //作 R/W、W/W 基本互斥控制 理論上可拿掉,是為了將第 1 個 reader 以外的
Semaphore rsem = 1 //作對 reader 不利之控制 reader 卡遠一點,讓 writer 全數做完後,讓
int readcount = 0 第 1 個 reader 搶先進去,且 writer 比
int writecount = 0 reader 稍微容易進入
Writer() Reader()
wait(y); wait(z);
writecount++; wait(rsem); //看可否通過對 reader 不利的控制
if(writecount == 1) wait(x);
wait(rsem); //築起對 reader 不利的控制 readcount++;
signal(y); if(readcount == 1)
wait(wsem); //通過 W/W 互斥 wait(wsem); //R/W 互斥
執行 writing signal(x);
wait(y); signal(rsem);
可 writecount--; signal(z);
移
到 if(writecount == 0) //No writer 執行 reading
signal(rsem); //解除對 reader 互斥 wait(x);
signal(wsem); //解除 W/W 互斥 readcount--;
signal(y); if(readcount == 0)
signal(wsem);
signal(x);
3. The Sleeping Barber Problem
(一)兩種 process :
• 理髮師(Barber)
沒有客人:被迫 wait
{
有客人:叫客人來剪髮,if 客人坐在 waiting chair
• 客人(Customer)
沒有 waiting chair:不進店裡
{ 理髮師 Busy:被迫 wait
有 waiting chair:進來坐下 {
理髮師 idle:叫醒 Barber
(三)解法
[法一]最多只允許 4 位哲學家上桌
⇒ 保證 Deadlock free
[法二]規定除非哲學家可同時取得左右兩根筷子,才准許持有,否則不得持有任何筷子
⇒ 打破 Hold & Wait
奇數號哲學家先拿左再拿右
[法三]規定 {
偶數號哲學家先拿右再拿左
⇒ 打破 Circular Waiting
[補充] 6 位(偶數)哲學家 -> 用刀叉
(法一) 大家先取得左邊(刀 or 叉),再取右邊(刀 or 叉)
⇒ 可能 Deadlock
(法二) 規定:大家先取刀,再取叉
⇒ Asymmetric ordering 取資源
⇒ 打破 Circular waiting
Semaphore 的種類
[區分角度一]由號誌值的值域做區分
○1 Binary Semaphore
1. Binary Semaphore
定義:號誌值只會為 0 或 1,不可為負數,不知有多少 Processes 卡在 wait 中
2. Counting Semaphore
定義:號誌值可以是負值,不限於 0 或 1,且若值為 -N,可知有 N 個 Processes 卡在 wait 中
◎ 用 Binary Semaphore 定出 Counting Semophore
宣告共享變數:
wait(value) signal(value)
wait(s1); wait(s1);
value = value – 1; value = value + 1;
if(value < 0){ if(value <= 0)//代表先前有 process 卡住
signal(s1); //先解 s1 互斥 signal(s2);
wait(s2); //在卡住自己 signal(s1); 前 value++,所以有等號
} //如果上面相反會 Deadlock
else
signal(s1);
[區分角度二]有無使用 Busy-waiting skill?
○1 有:也叫 Spinlock Semaphore
○
2 沒有:Non-Busy waiting Semaphore
1. Spinlock Semaphore
定義:Semaphore in wait operation 有使用 Busy-waiting skill 來使 process wait
wait:while(s<=0)do no-op;
s = s – 1;
signal:s = s + 1;
type Sempahore{
int value;
Q : a FIFO Queue for waiting process
}
Semaphore S;
wait(s): signal(s):
S.value = S.value – 1; S.value = S.value + 1;
if(s.value < 0){ if(s.value <= 0){
add process P to S.Q; romove process P from S.Q;
Block(P);//此為 System call, Wakeup(P);//此為 System call,
//P’s state : running -> Blocked //P’s state : Blocked -> Ready
} }
製作 Semaphore
(一) 想法:如何確保號誌值不會 Race Condition? ( wait / signal 是 atomic
operation )
∴方法
(1)Disable Interrupt
{
(2)C.S Design (SW solution /HW instrutuon support)
(二) 4 種 algo
Semaphore 定
Non-Busy waiting
義 Spinlock Semaphore
Semaphore
製作方法
Disable Interrupt [Algo1] [Algo3]
C.S Design [Algo2] [Algo4]
[Algo1]
Wait(S): Signal(S):
Disable interrupt; Disable interrupt;
S.value = S.value - 1; S.value = S.value + 1;
if(S.value < 0){ if(S.value <= 0){
add process P to S.Q; remove process P from S.Q;
Enable interrupt; Wakeup(P);
Block(P); }
} Enable interrupt;
else
Enable interrupt;
[Algo2]
no-op;
Disable interrupt; ○
關
}
S = S – 1;
Enable interrupt; ○
開
[Algo4]:同[Algo2]
type Monitor_monitor-Name{
var : 共享變數宣告;
procedure entry function_1_Name(參數)
begin
body
end
begin
初值設定
end
}
使用 Monitor 解決同步問題
例一、The Dinning Philosophers problem
Ⅰ.先定義 Monitor Type
repeat
hungry now
dp.puckup(i); //成功:進入 C.S(eating now) 失敗:Block 住,等別的 Pj 作 putdown
eating now //當 Pi 進入表示 Pi 不在 Monitor 內:Not Active
dp.putdown(i);
thinking now //Not Active
until false
○
2 process 卡住 (執行 x.wait)
與優先權無關:才是設計 Monitor 重點
{與優先權有關:只須告知 Monitor 內的 x 的 waiting Queue 及 entry Queue 是用 priority Queue
即可
RA.Apply(i);
使用資源
RA.Release(i)
...
}
使用 Monitor 定義 Semaphore (互斥用)
○3 P exit monitor right now and let B resume execution 救命恩人離開 monitor,
難民恢復執行
->Concurrent C/PASCAL 採用
(三)分析
類型 ○
1 難民先 ○
2 救命恩人先 ○
3 救命恩人離開 monitor,難民恢復執行
缺點 不保證難民一定可以 但與○
1 相比,沒那麼強
被恢復執行,因為在 理由:○
3 在救命恩人一進一出 Monitor 其間,
(1)保障「互斥」性質
{(2)難民先性質
(3)Condition x 變數的 x.wait 及 x.signal
(二)宣告共享變數
(三)製作 code
(1)確保互斥
方法:在 Monitor 的每個 procedure 開端及尾端加入額外控制碼
wait(mutex)
Body of Procedure
if(next-count > 0) //A 存在
Signal(next); //先救 B
else
Signal(mutex); //放外面的人進來
(2)製作 Condition x 變數
x.wait(){ x.signal(){
x-count++; //B 個數加 1 if(x-count > 0){ //有難民
if(next-count > 0) next-count++; //A 個數加 1
siganl(next); //B 卡住自己之前要先 signal(x-sem); //先救 B
else //解開 mutex wait(next); //A 卡住自己
signal(mutex); //但救命恩人比較重要應先救 next-count--; //if A 被放
wait(x-sem); //B 卡住自己 }
x-count--; //if B 被救 }
}
Symmetric
Direct Communication {
(一)可分為{ Asymmetric
Indirect Communication
(二)Direct Symmetric
定義:○ 收 、○
送 雙方必須指明對方 ID 才可以建立 Communication Link
Send(ID,msg)
指令 {
Receive(ID,msg)
(三) Direct Asymmetric
定義:只有○ 送 需指名 ID,○收 不須指名,所以從任何 process 收到皆可,但收到後要存對方
ID。
(四)Indirect Communication
定義:○ 收 、○送 是透過共享的 Mailbox 才可以建立 Communication Link
Send(Mailbox,msg)
指令 {
Receive(Mailbox,msg)
(五)比較表
Direct(symmetric) Indirect
○
收 、○
送 雙方必須指明對方 ID 才可以 ○
收 、○
送 是透過共享的 Mailbox 才可
Producer: Consumer:
repeat repeat
produce an item in nextp Receive(Producer,nextc);
Send(Consumer,nextp); consume the item in nextc
until false until false
在 Message Passing 下,如何呈現同步的感覺?
法一:Link Capacity
用兩種方式呈現 {
法二:Blcoking,Non-Blcoking 的 Send/Receive 指令組合
1. Zero Capacity
Ⅱ.○
送 :Link Capacity { 2. Bounded Capacity
3. Unbounded Capacity
送 送出訊息後,必須等到對方送出訊息,才可往下執行,
1. Zero Capacity:○
此種同步模式也叫 rendezvous (法文約會、偶遇的意思)
A: B:
Send(B,msg) Receive(A,msg)
Receive(B,”Ack”) Send(A,”Ack”)
送 無需等待
3. Unbounded Capacity:○
[法二] Blcoking,Non-Blcoking 的 Send/Receive 指令組合
○
1 Blocking Send:送出訊息後,必須等○ 收 收到,才往下執行
○
2 Non-Blocking Send:無須等待
○
3 Blocking Receive:收到訊息後才可往下執行
○
4 Non-Blcoking Receive:不管收到的訊息有沒有效,仍可往下執行