Upload
derek-bryan
View
231
Download
0
Embed Size (px)
Citation preview
Chapter 6: SynchronizationChapter 6: Synchronization
籃玉如籃玉如
Part Three: Process CoordinationPart Three: Process Coordination
Chapter 6 Synchronization
Chapter 7 Deadlocks
2
Chapter 6: SynchronizationChapter 6: Synchronization
6.1 Background
6.2 The Critical-Section Problem
6.3 Peterson’s Solution
6.4 Synchronization Hardware
6.5 Semaphores
6.6 Classic Problems of Synchronization
6.7 Monitors
6.8 Synchronization Examples
6.9 Atomic Transactions (X)
3
6.1 Background6.1 Background
Concurrent access to shared data may result in data inconsistency
Maintaining data consistency requires mechanisms to ensure the orderly execution of cooperating processes
Suppose that we wanted to provide a solution to the consumer-producer problem that fills all the buffers. We can do so by having an integer count that keeps track of the number of full buffers. Initially, count is set to 0. It is incremented by the producer after it produces a new buffer and is decremented by the consumer after it consumes a buffer.
4
Producer Producer
while (true)
{
/* produce an item and put in nextProduced
while (count == BUFFER_SIZE)
; // do nothing
buffer [in] = nextProduced;
in = (in + 1) % BUFFER_SIZE;
count++;
}
while (true)
{
while (count == 0)
; // do nothing
nextConsumed = buffer[out];
out = (out + 1) % BUFFER_SIZE;
count--;
/* consume the item in nextConsumed
}
ConsumerConsumer
5
Race ConditionRace Condition
count++ could be implemented as (in machine language)
register1 = count register1 = register1 + 1 count = register1
count-- could be implemented as
register2 = count register2 = register2 - 1 count = register2
Consider this execution interleaving with “count = 5” initially:
S0: producer execute register1 = count {register1 = 5}S1: producer execute register1 = register1 + 1 {register1 = 6} S2: consumer execute register2 = count {register2 = 5} S3: consumer execute register2 = register2 - 1 {register2 = 4} S4: producer execute count = register1 {count = 6 } S5: consumer execute count = register2 {count = 4}
6
6.2 The Critical-Section Problem6.2 The Critical-Section Problem
A system 包括 n 個 processes {p0, p1, …, pn-1}. 每一個 process 擁有一段程式片段 (the segment of code is called a critical section) , in this segment 這個 process 可以改變共同變數 (common variables) ,更新表格,寫入一的檔案等。 這樣系統的一個重要特性是當有一個 process 再這段 critical section 執
行某些運算時,其他的 processes 就不被允許對此 critical section 進行任何運算動作。
此稱為 The critical section problem ,它的設計主要的目的是作為cooperating processes 之間的 protocol
do {
entry section
critical section
exit section
remainder section
} while (TRUE);
7
Solution to Critical-Section ProblemSolution to Critical-Section Problem
要解決 the critical-section problem 必須滿足 3個要求:
1. Mutual Exclusion – 如果 process pi 正在執行它的 CS ,則其他之 processes 不得執行它們自己的 CS 。
2. Progress – 又稱為 lockstep synchronization ,沒有 process 正在執行 CS ,則欲進入 CS5 之 processes ( 非在 remainder section) 可以被 select 。
3. Bounded Waiting – 一個 已發出 request 之 process 經過一段時間 (bound) 應該會被 grant 。
8
6.3 Peterson’s Solution (Software Solution)6.3 Peterson’s Solution (Software Solution)
A classic software-based solution to the critical-section problem
解決兩個 processes 輪流在他們的 critical sections & remainder
sections 執行的問題 Assume that the LOAD and STORE instructions are atomic;
that is, cannot be interrupted. The two processes share two variables:
int turn; Boolean flag[2]
The variable turn indicates whose turn it is to enter the critical section.
The flag array is used to indicate if a process is ready to enter the critical section. flag[i] = true implies that process Pi is ready!
9
Algorithm for Process Algorithm for Process PPii
do {
flag[i] = TRUE;
turn = j;
while ( flag[j] && turn == j);
CRITICAL SECTION
flag[i] = FALSE;
REMAINDER SECTION
} while (TRUE);
10
6.4 Synchronization Hardware 6.4 Synchronization Hardware (Hardware Solution)(Hardware Solution)
硬體上的特殊性質可以使寫程式的工作變得比較容易,並且增進系統的效率。
Uniprocessors – could disable interrupts (i.e., 正在執行的 critical-section modifying 不能被中斷 ) to solve critical-section problem
Currently running code would execute without preemption
Generally too inefficient on multiprocessor systems
因為這個訊息必須傳給所有的 processors ,此具相當浪費時間,使的系統效能大為降低
Modern machines provide special atomic hardware instructions ,亦即可在一個 memory cycle 內完成,不可被切割 Atomic = non-interruptable
Test-and-set 與 swap 指令都是 indivisible ,即 executed atomically 於 1 個 memory cycle 。
11
Algorithm 1: TestAndndSet Instruction Algorithm 1: TestAndndSet Instruction
Definition:
boolean TestAndSet (boolean *target)
{
boolean rv = *target;
*target = TRUE;
return rv:
}
12
Shared boolean variable lock., initialized to false. Solution:
do {
while ( TestAndSet (&lock ))
; /* do nothing
// critical section
lock = FALSE;
// remainder section
} while ( TRUE);
Solution using TestAndSetSolution using TestAndSet
13
Algorithm 2: Swap InstructionAlgorithm 2: Swap Instruction
Definition:
void Swap (boolean *a, boolean *b)
{
boolean temp = *a;
*a = *b;
*b = temp:
}
14
Solution using SwapSolution using Swap
Shared Boolean variable lock initialized to FALSE; Each process has a local Boolean variable key.
Solution:
do {
key = TRUE;
while ( key == TRUE)
Swap (&lock, &key );
// critical section
lock = FALSE;
// remainder section
} while ( TRUE);15
Algorithm 3: Burn’s AlgorithmAlgorithm 3: Burn’s Algorithm
Bounding-waiting mutual exclusion with TestAndSet ()
Satisfies all the critical-section requirements The common data structures are Waiting [n]
and lock, both are initialized to false.
Boolean Waiting [n];
Boolean lock;
16
Burn’s AlgorithmBurn’s Algorithmdo {
waiting [i] = TRUE;
key = TRUE;
while ( waiting [i] && key )
key = TestAndSet (&lock);
waiting [i] = FALSE;
// critical section
j = ( I + 1 ) % n;
while (( j != i) && ! waiting [j] )
j = ( j+1 ) % n;
if ( j == i )
lock = FALSE;
else
waiting [j] = FALSE;
// remainder section
} while (TRUE);17
6.5 Semaphore6.5 Semaphore 由於 software & hardware solutions 很難應用到複雜的問題
,為了解決這個問題,可以使用 semaphore (a synchronization tool) 。
對應用程式設計者而言不像 software & hardware solutions複雜
Synchronization tool that does not require busy waiting
Semaphore S – integer variable
Can only be accessed via two indivisible (atomic) operations: S: wait() and signal()
Originally called P() and V()
18
6.5 Semaphore6.5 Semaphore
wait (S) {
while S <= 0
; // no-op
S--;
}
signal (S) {
S++;
}
19
Semaphore as General Synchronization ToolSemaphore as General Synchronization Tool
Counting semaphore – integer value can range over an unrestricted domain
Binary semaphore – integer value can range only between 0 and 1; can be simpler to implement
Also known as mutex locks
Can implement a counting semaphore S as a binary semaphore to deal with the critical-section problem for n processes
Provides mutual exclusion
Semaphore S; // initialized to 1
wait (S);
Critical Section
signal (S);
20
signal (S) { S++; }
Usage of SemaphoreUsage of Semaphore
Counting semaphore 可用在資源的管控上: S is initialized to n
每一個需要使用 resource 的 process 執行 wait ()
當一個 resource 被 release 時,執行 signal ()
當 S=0 時,則需要使用 resource 的 processes 就必須等待 Semaphore 也用來處理不同的同步問題,例如有兩個同步的
processes , P1 要執行 S1 指令,而 P2 要執行 S2 指令,但是 S2 得在 S1之後才能執行。 方法: p1 & P2 共享一個 semaphore synch (initial synach =0)
在 P1 加入 S1;
signal ();
在 P2 加入 wait (synch);
S2;
21
Semaphore ImplementationSemaphore Implementation
Must guarantee that no two processes can execute wait () and signal () on the same semaphore at the same time
Thus, implementation becomes the critical section problem where the wait and signal code are placed in the critical section.
Could now have busy waiting in critical section implementation
But implementation code is short
Little busy waiting if critical section rarely occupied
Note that applications may spend lots of time in critical sections and therefore this is not a good solution.
22
Semaphore Implementation with no Busy waitingSemaphore Implementation with no Busy waiting
With each semaphore there is an associated waiting queue. Each entry in a waiting queue has two data items:
value (of type integer)
pointer to next record in the list
Two operations:
block – place the process invoking the operation on the appropriate waiting queue.
wakeup – remove one of processes in the waiting queue and place it in the ready queue.
23
Semaphore Implementation with no Busy waitingSemaphore Implementation with no Busy waiting (Cont.)(Cont.)
Implementation of wait:
wait (S){
value--;
if (value < 0) {
add this process to waiting queue
block(); }
}
Implementation of signal:
Signal (S){
value++;
if (value <= 0) {
remove a process P from the waiting queue
wakeup(P); }
}
24
Deadlock and StarvationDeadlock and Starvation
Deadlock – two or more processes are waiting indefinitely for an event that can be caused by only one of the waiting processes 互相在等對方發出 signal ()
Let S and Q be two semaphores initialized to 1
P0 P1
wait (S); wait (Q);
wait (Q); wait (S);
. .
. .
signal (S); signal (Q);
signal (Q); signal (S);
Starvation – indefinite blocking. A process may never be removed from the semaphore queue in which it is suspended.
25
6.6 Classical Problems of Synchronization6.6 Classical Problems of Synchronization
These problems are used for testing nearly every newly proposed synchronization scheme.
Bounded-Buffer Problem
Readers and Writers Problem
Dining-Philosophers Problem
26
Bounded-Buffer ProblemBounded-Buffer Problem
N buffers, each can hold one item
Semaphore mutex initialized to the value 1
Semaphore full initialized to the value 0
Semaphore empty initialized to the value N.
27
Bounded Buffer Problem (Cont.)Bounded Buffer Problem (Cont.)
The structure of the producer process
do { // produce an item
wait (empty);
wait (mutex);
// add the item to the buffer
signal (mutex);
signal (full);
} while (true);
28
Bounded Buffer Problem (Cont.)Bounded Buffer Problem (Cont.)
The structure of the consumer process
do {
wait (full);
wait (mutex);
// remove an item from buffer
signal (mutex);
signal (empty);
// consume the removed item
} while (true);29
Readers-Writers ProblemReaders-Writers Problem
A data set is shared among a number of concurrent processes
Readers – only read the data set; they do not perform any updates
Writers – can both read and write.
Problem – allow multiple readers to read at the same time. Only one single writer can access the shared data at the same time.
30
Readers-Writers ProblemReaders-Writers Problem
Shared Data
Data set
Semaphore mutex initialized to 1.
Semaphore wrt initialized to 1.
Integer readcount initialized to 0.
31
Readers-Writers Problem (Cont.)Readers-Writers Problem (Cont.)
The structure of a writer process
do {
wait (wrt) ;
// writing is performed
signal (wrt) ;
} while (true)
32
Readers-Writers Problem (Cont.)Readers-Writers Problem (Cont.)
The structure of a reader process
do {
wait (mutex) ;
readcount ++ ;
if (readercount == 1) wait (wrt) ;
signal (mutex)
// reading is performed
wait (mutex) ;
readcount - - ;
if redacount == 0) signal (wrt) ;
signal (mutex) ;
} while (true)
33
Dining-Philosophers ProblemDining-Philosophers Problem
Shared data
Bowl of rice (data set)
Semaphore chopstick [5] initialized to 1
34
Dining-Philosophers Problem (Cont.)Dining-Philosophers Problem (Cont.)
The structure of Philosopher i:
Do {
wait ( chopstick[i] );
wait ( chopStick[ (i + 1) % 5] );
// eat
signal ( chopstick[i] );
signal (chopstick[ (i + 1) % 5] );
// think
} while (true) ;
35
Problems with SemaphoresProblems with Semaphores
Incorrect use of semaphore operations:
signal (mutex) …. wait (mutex)
wait (mutex) … wait (mutex)
Omitting of wait (mutex) or signal (mutex) (or both)
36
6.7 Monitors6.7 Monitors
A high-level abstraction that provides a convenient and effective mechanism for process synchronization
包括 data 以及 procedures
Only one process may be active within the monitor at a time
37
6.7 Monitors6.7 Monitors
monitor monitor-name
{
// shared variable declarations
procedure P1 (…) { …. }
…
procedure Pn (…) {……}
Initialization code ( ….) { … }
…
}
}
38
Fig. 6.18 Syntax of a monitor
Schematic view of a MonitorSchematic view of a Monitor
39
MonitorsMonitors
Monitor 結構可確保在一個時間點只有一個 process在 monitor 中執行。
40Fig. 6.19 Schematic view of a monitor
MonitorsMonitors
雖然 programmer 不需要明確的寫 synchronization constraint 的程式碼,但仍需定義 additional synchronization mechanisms 。 This mechanisms are provided by the
condition construct.
41
MonitorsMonitors
condition x, y;
Two operations on a condition variable:
x.wait () – a process that invokes the operation is
suspended.
x.signal () – resumes one of processes (if any) tha
invoked x.wait ()
如果沒有 process 在 suspend 則 signal operation 沒有任何動作 ( 與 P / V 不同, V 每次都會影響semaphore)
42
Monitor with Condition VariablesMonitor with Condition Variables
43Fig. 6.20
MonitorsMonitors
如果 process P 引發 x.signal () 時,正有一個 process Q 是在等 x condition ,則有以下兩種情形: Signal and wait.
P either waits until Q leaves the monitor or waits for another condition.
Signal and continue.
Q either waits until P leaves the monitor or waits for another condition.
44
6.7.2 Solution to Dining Philosophers6.7.2 Solution to Dining Philosophers
monitor DP
{
enum { THINKING; HUNGRY, EATING) state [5] ;
condition self [5];
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 neighbors
test((i + 4) % 5);
test((i + 1) % 5);
} 45
Solution to Dining Philosophers (cont)Solution to Dining Philosophers (cont)
void test (int i) {
if ( (state[(i + 4) % 5] != EATING) &&
(state[i] == HUNGRY) &&
(state[(i + 1) % 5] != EATING) ) {
state[i] = EATING ;
self[i].signal () ;
}
}
initialization_code() {
for (int i = 0; i < 5; i++)
state[i] = THINKING;
}
} 46
6.7.3 Implementing a Monitor Using Semaphores6.7.3 Implementing a Monitor Using Semaphores
對每一個 monitor 提一個 semaphore: mutex (initialized to 1) 。每一個行程在進入 monitor 之前,都必須先執行 wait (mutex) 的動作,並在離開 monitor 之後,執行 signal (mutex) 的動作。
因為一個 signaling process 可能必須等待,直到 the resumed process 離開 monitor 或是等待,所以增加一個semaphore: next (initialized to 0).
The signaling processes may suspend themselves on next semaphore.
next_count: an integer variable
To count the number of processes suspended on next
47
6.7.3 Implementing a Monitor Using Semaphores6.7.3 Implementing a Monitor Using Semaphores
Each external procedure F:
wait (mutex);
…
body of F
…
if (next_count > 0)
signal (next);
else
signal (mutex);
48
6.7.3 Implementing a Monitor Using Semaphores6.7.3 Implementing a Monitor Using Semaphores
Condition x:
semaphore x_sem (initialized to 0)
x_count (an integer, initialized to 0)
49
6.7.4 Resuming Processes Within a Monitor6.7.4 Resuming Processes Within a Monitor
可能有以下問題,在 Chap 17 System Protection 再討論 一個 process 可能在沒有先取得某項資源的
存取允許權之前就先使用該資源。 一個 process 在獲得某項資源的存取權之後
,就佔住不放。 一個 process 可能會試圖釋放一項從未取得
過的資源。 一個 process 可能會對相同的資源提出兩次
要求 ( 沒有先釋放出該資源 ) 。50