6.1 operating system concepts 第六章 行程同步 n 背景資料 n critical-section 問題 n...
Post on 19-Dec-2015
267 views
TRANSCRIPT
6.1Operating System Concepts
第六章 行程同步
背景資料 Critical-Section 問題 同步硬體 (Synchronization Hardware) 訊號機 (Semaphores) 同步的典型問題 Critical Regions Monitors Solaris 2 & Windows 2000 內部的同步機制
6.2Operating System Concepts
背景資料
共享資料的同時操作可能會造成資料的不一致 . 為了要維持共享資料的一致性需要可確認的合作行程間的順序執行的一些機制 .
第 3 章的共享記憶體解決方案的有限緩衝區問題共享記憶體 (bounded buffer problem)允許最多同時有 N – 1 項目在共享的緩衝區中一個可以有 N 個項目同時使用的緩衝區 機制並非容易 .假使我們修改了這個 producer-consumer 的程式碼
加入一個 counter 變數 , 它的啟始值是 0 當 producer 加入一個項目時, counter 值會加 1 當 consumer 拿掉一個項目時, counter 值會減 1
6.3Operating System Concepts
有限緩衝區 (Bounded-Buffer)
共享資料
#define BUFFER_SIZE 10typedef struct {
. . .} item;item buffer[BUFFER_SIZE];int in = 0;int out = 0;int counter = 0;
6.4Operating System Concepts
Bounded-Buffer 生產者行程 (Producer process)
item nextProduced;
while (1) {while (counter == BUFFER_SIZE)
; /* do nothing */buffer[in] = nextProduced;in = (in + 1) % BUFFER_SIZE;counter++;
}
6.5Operating System Concepts
Bounded-Buffer
消費者行程 (Consumer process)
item nextConsumed;
while (1) {while (counter == 0)
; /* do nothing */nextConsumed = buffer[out];out = (out + 1) % BUFFER_SIZE;counter--;
}
6.6Operating System Concepts
Bounded Buffer
程式中的下列敘述
counter++;counter--;
必須要以極細微 (atomically) 的方式處理 .
Atomic operation就是一個操作必須要從頭到尾完全執行完畢,中間不能出現插斷 (Interrupt).
6.7Operating System Concepts
Bounded Buffer
程式 “ count++” 可以用下列的機器語言來製作 :register1 = counterregister1 = register1 + 1counter = register1
程式 “ count--” 可以以下列的機器語言來製作 :
register2 = counterregister2 = register2 – 1counter = register2
6.8Operating System Concepts
Bounded Buffer
假使生產者與消耗者同時嘗試去使用共享緩衝區 , 前面所討論的組合語言程式可能會互相交錯 .
互相交錯的執行結果就要看生產者及消耗者行程的執行排班結果 .
6.9Operating System Concepts
Bounded Buffer
假使 counter 的初始值是 5. 一種互相交錯程式交錯的例子如下 :producer: register1 = counter (register1 = 5)producer: register1 = register1 + 1 (register1 = 6)consumer: register2 = counter (register2 = 5)consumer: register2 = register2 – 1 (register2 = 4)producer: counter = register1 (counter = 6)consumer: counter = register2 (counter = 4)
Count 值可能是 4 或者 6, 然而正確值是 5.
6.10Operating System Concepts
競爭狀況 (Race Condition)
Race condition: 當幾個行程同時存取及處理分享資料,分享資料的最後結果要看哪一個行程最後結束 .
避免競爭狀況 , 同時執行的多個行程必須要同步 .
6.11Operating System Concepts
Critical-Section 問題
N 個行程都搶著使用某個共享資料 每個行程有一段程式碼,叫做 critical section, 程式碼中會使用該共享資料 .
問題必須要確認一個行程正在 critical section 執行時,沒有其它的行程是可以進入自己的 critical section程式碼 .
6.12Operating System Concepts
Critical-Section Problem 的解決方案
1. Mutual Exclusion.( 互斥 )假使行程 Pi 正在 critical section 中執行 , 其它的行程不可以在
他們自己的 critical sections 中執行 .
2. Progress.( 一直能進行 )假使沒有任何行程在自己的 critical section 中執行,而且其中有
些行程希望進入他們自己的 critical section, 然後要選出行程接著進入 critical section ,這個選擇的動作不可以被無限延遲 .
3. Bounded Waiting.( 有限等候時間 ) 當一個行程允許進入 critical sections 之後,其他行程被允許
進入自己的 critical sections 的等候時間必須是有限的 . 假使每一個行程是以非 0 的速度執行 . 沒有有關於這 n 個行程的相對執行速度 .
6.13Operating System Concepts
解決問題的第一次嘗試
只有兩個行程: P0 及 P1
行程 Pi的一般結構 ( 其他行程 Pj)
do {entry section
critical sectionexit section
reminder section} while (1);
行程可以分享共用的變數來達到同步 .
6.14Operating System Concepts
Algorithm 1
共享變數 : int turn;
一開始 turn = 0 turn= i Pi can enter its critical section
Process Pi
do {while (turn != i) ;
critical sectionturn = j;
reminder section} while (1);
滿足 mutual exclusion, 但是不滿足 progress
6.15Operating System Concepts
Algorithm 2
共享變數 boolean flag[2];
一開始 flag[0] = flag[1] = false. flag[i]= true Pi ready to enter its critical section
Process Pi
do {flag[i] := true;while (flag[j]) ;
critical sectionflag [i] = false;
remainder section} while (1);
滿足 mutual exclusion, 但不滿足 progress 的要求 .
6.16Operating System Concepts
Algorithm 3
將前面兩個演算法的共享變數結合 . Process Pi
do {flag [i]:= true;turn = j;while (flag [j] and turn = j) ;
critical sectionflag [i] = false;
remainder section} while (1);
滿足了解決 critical section 問題的三個條件 ; 也就是解決了只有兩個行程間的 critical-section 問題 .
6.17Operating System Concepts
Bakery Algorithm
在進入自己的 critical section, 行程會收到一個數字 . 擁有最小數字的行程可以進入自己的critical section.
假使行程 Pi and Pj 得到同樣大小的號碼,而 i
< j, 這樣 Pi 就先進入自己的 critical section;
不然 Pj 先進入自己的 critical section. 這樣的數字編號方式會一直產生遞增的數字表列
i.e. 1,2,3,3,3,3,4,5...
N個行程的 Critical Section 問題
6.18Operating System Concepts
Bakery Algorithm
符號 < 定義成英文字母順序 (ticket #, process id #) (a,b) < (c,d) if a < c or if a = c and b < d max(a0,…, an-1) is a number, k, such that k ai for i
= 0, …, n – 1 共享資料
boolean choosing[n];int number[n];
所有相關資料結構的起始值分別設成 false 及 0
6.19Operating System Concepts
Bakery Algorithm
do { choosing[i] = true;number[i] = max(number[0], number[1], …, number [n – 1])+1;choosing[i] = false;for (j = 0; j < n; j++) {
while (choosing[j]) ; while ((number[j] != 0) &&
(number[j],j)<( number[i],i))) ;}
critical sectionnumber[i] = 0;
remainder section} while (1);
6.20Operating System Concepts
Synchronization Hardware
一次做完 (atomically)測試及變更記憶體中一個 word 的內容 .
boolean TestAndSet(boolean &target) {boolean rv = target;tqrget = true;return rv;
}
6.21Operating System Concepts
Mutual Exclusion with Test-and-Set
共享資料 : boolean lock = false;
Process Pido {
while (TestAndSet(lock)) ;critical section
lock = false;remainder section
}
6.22Operating System Concepts
同步硬體
Atomically swap two variables.
void Swap(boolean &a, boolean &b) {boolean temp = a;a = b;b = temp;
}
6.23Operating System Concepts
Mutual Exclusion with Swap
Shared data (initialized to false): boolean lock;
boolean waiting[n];
Process Pi
do {key = true;while (key == true)
Swap(lock,key);critical section
lock = false;remainder section
}
6.24Operating System Concepts
訊號機 (Semaphores)
不需要 busy waiting 的同步方法 . (訊號) Semaphore S – 一個整數變數 這個訊號變數只可以被兩個獨立的內建操作所使
用 ( 這兩個內建的操作必須是 atomic) wait (S):
while S 0 do no-op;S--;
signal (S): S++;
6.25Operating System Concepts
Critical Section of n Processes
Shared data: semaphore mutex; //initially mutex = 1
Process Pi:
do { wait(mutex); critical section
signal(mutex); remainder section} while (1);
6.26Operating System Concepts
訊號機的製作
將一個 semaphore 定義為一個 recordtypedef struct { int value; struct process *L;} semaphore;
假使有兩個簡單的操作 : block 會暫停呼叫訓號機的行程 . wakeup(P) 會重新啟動被暫停的行程 P.
6.27Operating System Concepts
Implementation
訊號機的兩個操作會以下列的方式定義wait(S):
S.value--;if (S.value < 0) {
add this process to S.L;block;
}
signal(S): S.value++;if (S.value <= 0) {
remove a process P from S.L;wakeup(P);
}
6.28Operating System Concepts
利用訊號機當作是一個行程同步的工具
在執行行程 Pj 內的 B 區塊一定是在 Pi內的 A 區塊執行完畢後
使用初始值為 0 的訊號變數 flag Code:
Pi Pj A wait(flag)
signal(flag) B
6.29Operating System Concepts
死結及枯竭 死結 (Deadlock) – 兩個或兩個以上的行程正無限期的等待一個在等待行程當中的唯一一個行程的事件發生
讓 S 及 Q 是起始值是 1 的兩個訊號P0 P1wait(S); wait(Q);wait(Q); wait(S); signal(S); signal(Q);signal(Q)signal(S);
枯竭 (Starvation) – 無限期暫停 . 一個行程被暫停後從來沒有從訊號機佇列中離開 .
6.30Operating System Concepts
兩種型態的訊號機
計數訊號機 (Counting semaphore) – 訊號變數的整數值可以是無限制的範圍 .
二元訊號機 (Binary semaphore) – 訊號變數的整數值可以是 0 或 1; 這樣的訊號機較容易製作 .
可以用二元訊號機來製作計數訊號機 .
6.31Operating System Concepts
以二元訊號機製作計數訊號機 S
資料結構 :binary-semaphore S1, S2;int C:
起始值 :S1 = 1S2 = 0C = initial value of semaphore S
6.32Operating System Concepts
訊號機 S 的製作 wait operation
wait(S1);C--;if (C < 0) {
signal(S1);wait(S2);
}signal(S1);
signal operationwait(S1);C ++;if (C <= 0)
signal(S2);else
signal(S1);
6.33Operating System Concepts
同步的典型問題
Bounded-Buffer Problem
Readers and Writers Problem
Dining-Philosophers Problem哲學家的晚餐問題
6.34Operating System Concepts
Bounded-Buffer Problem
共享資料
semaphore full, empty, mutex;
起始值 :
full = 0, empty = n, mutex = 1
6.35Operating System Concepts
Bounded-Buffer Problem Producer Process
do { … produce an item in nextp …
wait(empty); wait(mutex); … add nextp to buffer … signal(mutex); signal(full);} while (1);
6.36Operating System Concepts
Bounded-Buffer Problem Consumer Process
do { wait(full)wait(mutex);
…remove an item from buffer to nextc
…signal(mutex);signal(empty);
…consume the item in nextc
…} while (1);
6.37Operating System Concepts
Readers-Writers Problem
共享資料
semaphore mutex, wrt;
起始值
mutex = 1, wrt = 1, readcount = 0
6.38Operating System Concepts
Readers-Writers Problem Writer Process
wait(wrt); …
writing is performed …
signal(wrt);
6.39Operating System Concepts
Readers-Writers Problem Reader Process
wait(mutex);readcount++;if (readcount == 1)
wait(wrt);signal(mutex);
…reading is performed
…wait(mutex);readcount--;if (readcount == 0)
signal(wrt);signal(mutex):
6.40Operating System Concepts
哲學家晚餐問題
共享資料 semaphore chopstick[5];
起始值均為 1
6.41Operating System Concepts
哲學家晚餐問題
Philosopher i:do {
wait(chopstick[i])wait(chopstick[(i+1) % 5])
…eat …
signal(chopstick[i]);signal(chopstick[(i+1) % 5]);
…think …
} while (1);
6.42Operating System Concepts
Critical Regions
高層次的同步建構 一個型態為 T 的共享變數 v, 被宣告成 :
v: shared T 變數 v 只能在下列程式敘述中使用
region v when (B) do S
其中 B 是一個布林表示式 .
當敘述 S 正在執行的同時,其它的行程不可同時存取變數 v.
6.43Operating System Concepts
Critical Regions
來自不同行程 Regions若有參考到相同的共享變數會及時避開其他行程 .
當一個行程嘗試執行 region statement, 其中布林表示氏 B 會被求值 . 如果 B 是 true, 敘述S 就會被執行 . 如果不成立 , 行程會一直延遲直到 B 成立為止,而且其他行程也不會進入與變數 v 有關自己的 region 中 .
6.44Operating System Concepts
範例: Bounded Buffer
共享資料 :
struct buffer {int pool[n];int count, in, out;
}
6.45Operating System Concepts
Bounded Buffer Producer Process
生產者行程加了 nextp 項目到共享的緩衝區中
region buffer when( count < n) {pool[in] = nextp;in:= (in+1) % n;count++;
}
6.46Operating System Concepts
Bounded Buffer Consumer Process
消耗者行程從共享緩衝區中移除一個項目,然後將它放入 nextc
region buffer when (count > 0) {nextc = pool[out];out = (out+1) % n;count--;
}
6.47Operating System Concepts
將 region x when B do S 製作出來
與共享變數有關的其他變數如下 :semaphore mutex, first-delay, second-delay; int first-count, second-count;
進入 critical section 的互斥處理是由mutex 所提供 .
假如一個行程無法進入自己的 critical section因為布林表示式 B 不成立 , 它一開始會等在 first-delay 訊號 ; 然後在它被允許重新計算 B 的條件式值時之前,它會移到 second-delay 等待 .
6.48Operating System Concepts
Implementation
分別用等待在訊號 first-delay and second-delay 以及分別對應的 first-count 及second-count 來追蹤等待的行程 .
該演算法假設行程等待訊號的佇列處理是以一個FIFO 來排隊 .
對於任意其它的佇列等待方式,會需要比較複雜的製作方式 .
6.49Operating System Concepts
Monitors
是高階的同步製作:允許同時動作的多行程共享一個抽象資料型態 .
monitor monitor-name{
shared variable declarationsprocedure body P1 (…) {
. . .}procedure body P2 (…) {
. . .} procedure body Pn (…) {
. . .} {
initialization code}
}
6.50Operating System Concepts
Monitors
允許一個行程在 monitor 中等待 , 一個條件變數必須以下面的方式宣告:
condition x, y; 條件變數只能跟wait and signal 兩個操作一
起使用 . The operation x.wait();意味著行程在呼叫這個操作後會暫停,一直到另外一個行程呼叫
x.signal(); 這個 x.signal 操作會只啟動一個被暫停的行程 . 假
使沒有行程被暫停,這個操作並不會有其他動作 .
6.51Operating System Concepts
一個 Monitor 的概要圖
6.52Operating System Concepts
有條件變數的 Monitor
6.53Operating System Concepts
哲學家晚餐範例
monitor dp {
enum {thinking, hungry, eating} state[5];
condition self[5];void pickup(int i) // following slidesvoid putdown(int i) // following slidesvoid test(int i) // following slidesvoid init() {
for (int i = 0; i < 5; i++)state[i] = thinking;
}}
6.54Operating System Concepts
哲學家晚餐void pickup(int i) {
state[i] = hungry;test[i];if (state[i] != eating)
self[i].wait();}
void putdown(int i) {state[i] = thinking;// test left and right neighborstest((i+4) % 5);test((i+1) % 5);
}
6.55Operating System Concepts
哲學家晚餐
void test(int i) {if ( (state[(I + 4) % 5] != eating) && (state[i] == hungry) && (state[(i + 1) % 5] != eating)) {
state[i] = eating;self[i].signal();
}}
6.56Operating System Concepts
利用訊號機製作 Monitor 變數
semaphore mutex; // (initially = 1)semaphore next; // (initially = 0)int next-count = 0;
每一個外在的程序 F 會被換成wait(mutex); … body of F; …if (next-count > 0)
signal(next)else
signal(mutex);
在 monitor 中的互斥使用是已經確定的 .
6.57Operating System Concepts
Monitor Implementation
對每一個條件變數 x, 我們有 :semaphore x-sem; // (initially = 0)int x-count = 0;
操作 x.wait 可以被製作成 :
x-count++;if (next-count > 0)
signal(next);else
signal(mutex);wait(x-sem);x-count--;
6.58Operating System Concepts
Monitor Implementation
操作 x.signal 可以製作成 :
if (x-count > 0) {next-count++;signal(x-sem);wait(next);next-count--;
}
6.59Operating System Concepts
Monitor Implementation
Conditional-wait 的建構 : x.wait(c); c – 當這個 wait 操作執行時,會去計算這個整數表示式的值 .
c 的值 ( 一個優先權號碼 ) 會存到一個被暫停的對應行程中 .
當 x.signal 執行時 ,具有最小優先權號碼的行程接下來會被啟動 .
檢查建立正確系統的兩個條件 : 眾多使用者行程每次在 monitor 的呼叫必須有一個正確的順序 .
必須確認一個不配合的行程不可忽視由monitor 所提供的互斥處理介面,能在沒有使用這樣的存取協定時而能直接實用分享資源 .
6.60Operating System Concepts
Solaris 2 Synchronization
製作不同的鎖定機制 (locks) 來支援多工,多執行緒 (包含即時執行緒 ), 及多處理器 .
利用可微調的互斥的 mutex 訊號機來有效保護較短程式中共用的資料 .
當較長的區塊的程式碼需要使用共享資料時,利用條件變數和 readers-writers鎖定資料 .
利用十字旋轉門的方式來排列等待的執行緒串列,同時這些執行緒可以要求資料的存取是使用可微調的互斥的 mutex 訊號機或是使用 readers-writers鎖定資料 .
6.61Operating System Concepts
Windows 2000 Synchronization
使用插斷遮罩來保護在單 CPU系統上的共用資源 .
在多處理器上使用 spinlocks. 也提供可以向互斥訊號或訊號機一樣運作的派遣物件 (dispatcher objects).
派遣物件也可以提供事件 . 一個事件就很像是一個條件變數 .
6.62Operating System Concepts
Bounded Buffer MonitorMonitor bb{ item buffer[10]; int in = 0, out = 0, count = 0; condition notFull = 0; condition notEmpty = 0; void produce(double nextproduced); item consume(void); void produce(double nextproduced) { if (count == 10) notFull.wait(); buffer[in] = nextproduced; in = (in+1) % 10; count++; if (count == 1) notEmpty.signal(); }
item consume() { item result; if (count == 0) notEmpty.wait(); result = buf[out]; out = (out+1) % 10; count--; if (count == 9) notFull.signal(); return result; }}
Process 1 bb.produce(newitem);
Process 2 info=bb.consume();