Presentation is loading. Please wait.

Presentation is loading. Please wait.

Chapter 6 Process Synchronization

Similar presentations


Presentation on theme: "Chapter 6 Process Synchronization"— Presentation transcript:

1 Chapter 6 Process Synchronization
Background The Critical-Section Problem Peterson’s Solution Synchronization Hardware Mutex Locks Semaphores Classic Problems of Synchronization Monitors Synchronization Examples Alternative Approaches

2 How do cooperating processes share data?
6.1 Background How do cooperating processes share data? Directly share a logical address space (threads) Share data only through files Concurrent access to shared data may result in data inconsistency Need mechanisms to ensure the orderly execution of cooperating processes that share a logical address space Example Solution to the bound-buffer problem (見下頁)

3 6.1 Background: The Bounded-Buffer Scheme
producer thread consumer thread while (count == BUFFER_SIZE) ; // no-op // add an item to the buffer ++count; buffer[in] = item; in = (in+1) % BUFFER_SIZE; while (count == 0) ; // no-op // remove an item from the buffer --count; item = buffer[out]; out = (out+1) % BUFFER_SIZE; in out

4 6.1 Background: The Bounded-Buffer Scheme
Although both the producer and consumer routines are correct separately, they may function incorrectly when executed concurrently ++count count What happens if count = 5 and register1 = count register1 = register count = register1 register2 = count register2 = register count = register2 register1 = count register1 = register register2 = count register2 = register count = register1 count = register2 {register1 = 5} {register1 = 6} {register2 = 5} {register2 = 4} {count = 6} {count = 4}

5 6.1 Background: The Bounded-Buffer Scheme
The statements count++; count--; must be performed atomically Atomic operation means an operation that completes in its entirety without interruption

6 6.1 Background Race condition
The situation where several processes access and manipulate shared data concurrently The final value of the shared data depends upon which process finishes last To prevent race conditions, concurrent processes must be synchronized (同步化) Process synchronization and coordination

7 6.2 The Critical-Section Problem
Each process has a segment of code, called a Critical Section, where the process may be changing common variables, updating a table, writing a file, etc The execution of critical sections by the processes is mutually exclusive in time When one process is executing in its critical section, no other process is allowed to execute its critical section The critical-section problem is to design a protocol that processes can use to cooperate

8 Relative speed of the n processes are unknown entry section
6.2 The Critical-Section Problem: General Structure of a Typical Process Relative speed of the n processes are unknown entry section Section of code that requests permission to enter critical section exit section Section of code that follows critical section remainder section Remaining code do { entry section critical section exit section remainder section } while (1);

9 6.2 The Critical-Section Problem: Solution Requirements
Mutual exclusion If process Pi is executing in its CS, then no other processes can be executing in their CSs Progress If no process is executing the CS and someone, e.g. Pj , wants in, eventually Pj will get in Bounded waiting Pi wants to enter CS Any Pj enters its CS at most N times after Pi’s request After N entries, Pi must enter its CS N must be bounded

10 6.3 Peterson’s Solution A software-based solution to the critical-section problem (two process solution) Assume that the LOAD and STORE instructions are atomic; that is, cannot be interrupted Two processes (Pi, Pj) (或P0, P1 ) share two variables int turn; boolean flag[2]; The variable turn indicates whose turn it is to enter the critical section 若turn == i,代表容許process i進入CS The flag array indicates if a process is ready to enter the critical section. flag[i] = true implies that process Pi is ready!

11 6.3 Peterson’s Solution: Algorithm for Process Pi
do { flag[i] = true; turn = j; while (flag[j] && turn == j); CRITICAL SECTION flag[i] = false; REMAINDER SECTION } while (true);

12 6.3 Peterson’s Solution: Proof
Claim: Mutual exclusion is preserved Proof: (反證法) Assume Pi and Pj in CS at the same time flag[i] && flag[j] == true (case 1) flag[j] && turn == j  false  turn = i (case 2) flag[i] && turn == i  false  turn = j turn cannot be i and j at the same time do { flag[i] = true; turn = j; while (flag[j] && (turn == j)); critical section flag[i] = false; remainder section } while (1);

13 6.3 Peterson’s Solution: Proof
do { flag[i] = true; turn = j; while (flag[j]&&(turn == j)); critical section flag[i] = false; remainder section } while (1); 6.3 Peterson’s Solution: Proof Claim: Progress is met Proof: Pi is stuck at “flag[j] && turn == j” while loop (case 1) Pj is not ready to enter the CS flag[j] == false  Pi can enter (case 2) Pj is ready to enter the CS Pj sets flag[j] to true and at its while Observe: turn == i XOR turn == j (case 2.1) turn == i  Pi will enter (case 2.2) turn == j  Pj will enter Pj leaves CS; sets flag[j] to false Pi enters Pj leaves CS; sets flag[j] to true; then sets turn to i  Pi enters (Pi at while cannot change turn) Pi (Pj) will enter the CS (progress) after at most one entry by Pj (Pi) (bounded waiting)

14 補充:Multiple-Process Solution (Bakery Algorithm)
Lamport’s bakery algorithm (for n processes) Before entering its critical section, process receives a number. Holder of the smallest number enters the critical section If processes Pi and Pj receive the same number, if i < j, then Pi is served first; else Pj is served first The numbering scheme always generates numbers in increasing order of enumeration, e.g., 1,2,3,3,3,3,4,5...

15 補充:Multiple-Process Solution (Bakery Algorithm)
Notations “<“ lexicographical order (ticket #, process id #) (a,b) < (c,d) if a < c or if a = c and b < d 例 (2,4) < (5,3); (6,2) < (6,5) max(a0,…, an-1) is a number, k, such that k  ai for i = 0,…, n – 1 Shared data boolean choosing[n]; int number[n]; Data structures are initialized to false and 0, respectively

16 補充:Multiple-Process Solution (Bakery Algorithm)
Process Pi 執行的演算法 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 section number[i] = 0; remainder section } while (1);

17 Bakery Algorithm: What if Choosing is Removed?
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 section number[i] = 0; remainder section } while (1); P2 P4 number[2] = 0 number[4] = 0 calculate the max value calculate the max value number[4] = 1 number[2] = 1 enter CS enter CS

18 Summary: CS Solution Validation
When two or more processes want in, is it possible that more than one actually get in? When a process is already in, is it possible that another gets in? When no one is in CS, does any process need to wait? When one is waiting, is it possible that infinitely many processes can run over it? 習題6.2與6.3,期末考前完成

19 6.4 Synchronization Hardware
Makes the programming task easier Improves system efficiency Solution in a uni-processor environment Disallow interrupts to occur while a shared variable is being modified DISABLE INTERRUPTS Critical section ENABLE INTERRUPTS Result: no preemption Solution in a multi-processor environment Require special hardware instructions

20 6.4 Synchronization Hardware: TestAndSet() Instruction
Test and modify the content of a word atomically boolean TestAndSet(boolean *target) { boolean rv = *target; *target = true; return rv; } Mutual exclusion with TestAndSet Process Pi do { while (TestAndSet(&lock)) ; critical section lock = false; remainder section } while (true); Shared boolean variable; initialized to false Data structures containing different sized words refer to them as WORD (16 bits/2 bytes), DWORD (32 bits/4 bytes) and QWORD (64 bits/8 bytes) respectively.

21 參考來源 TRUE 在多個執行緒並行的工作環 境中,先執行TestAndSet()指令者取得先機,得到lock為false的回傳結果同時把lock設為true,使得其他執行緒被阻絕在外,達到互斥效果

22 6.4 Synchronization Hardware: compare_and_swap()
int compare_and_swap(int *value, int expected, int new_value) { int temp = *value; if (*value == expected) *value = new_value; return temp; } 設全域變數lock(整數型態,初值0)被所有程序共用 Process Pi do { while (compare_and_swap(&lock,0,1) != 0); critical section lock = 0; remainder section } while (true); 呼叫compare_and_swap()當下的第一個參數之原始狀態值回傳出來 It compares the contents of a memory location with a given value and, only if they are the same, modifies the contents of that memory location to a new given value.

23 6.4 Synchronization Hardware: Bounded-Waiting Mutual Exclusion with TestAndSet()
do { 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 (1); 證明此演算法解決critical-section problem

24 6.5 Mutex Locks Previous solutions are complicated and generally inaccessible to application programmers OS designers build software tools to solve critical section problem Simplest is mutex (mutual exclusion) lock Protect critical regions with it by first acquire() a lock then release() it Boolean variable indicating if lock is available Calls to acquire() and release() must be atomic Implemented via hardware atomic instructions But this solution requires busy waiting This lock is called a spinlock

25 6.5 Mutex Locks acquire() { while (!available) ; /* busy wait */ available = false; } release() { available = true; do { acquire lock critical section release lock remainder section } while (true);

26 使用Mutex的實例 (完整程式碼可於課程網頁取得)

27 Operating System and Programming Language Constructs for Concurrency
Semaphores Monitors Conditional critical regions Message passing

28 6.6 Semaphores (旗語) Previous solutions for the critical-section problem are not easy to generalize to more complex problems To overcome this, a synchronization tool, called a semaphore, can be used A semaphore is an integer variable that is accessed only through two standard atomic operations Wait (P operation) Signal (V operation) wait(S): while (S <= 0) ; S --; signal(S): S ++; P: proberen (“to test”) V: verhogen (“to increment”)

29 6.6 Semaphores: Usage To deal with n-processes critical-section problem To synchronize processes For example, if we want to execute S1 and then S2 S1; signal(synch); wait(synch); S2; do { wait(mutex); critical section signal(mutex); remainder section } while (1); P P2 synch initialized to 0 n processes share a semaphore, mutex, initialized to 1

30 6.6 Semaphores: Implementation
Busy waiting When a process is in its critical section, any other process trying to enter its critical section must loop continuously in the entry code Wastes CPU cycles This type of semaphore is also called a spinlock In multiprocessor systems spinlock is useful (no context switch is required) when locks are expected to be held for short times

31 6.6 Semaphores: Implementation
To free from busy waiting When a process has to wait for a semaphore Place the process into a waiting queue associated with the semaphore Switch the state of the process to the waiting state Transfer the control to the CPU scheduler Select another process to execute When a process executes signal operation wakeup a process by changing its state to ready Place the process in the Ready queue

32 6.6 Semaphores: Implementation
Define a semaphore as a record typedef struct process { int value; struct process *L; } semaphore; Assume two simple operations block suspends the process that invokes it wakeup(P) resumes a blocked process P S->value --; if (S->value < 0) { add this process to S->L; block(); } S->value ++; if (S->value <= 0) { remove a process P from S->L; wakeup(P); } wait(S) signal(S)

33 6.6 Semaphores: Implementation
Atomicity of signal and wait operations signal and wait should be executed atomically In a uni-processor environment Inhibit interrupt when the operation is executing In a multi-processor environment Employ any correct software solution to the critical section problem The critical sections consist of the wait and signal procedures

34 Example of Semaphore Mechanism* (1/4)
A,B,C depend on a result from D. A Processor S=1 B D C Ready list Suspended list 1 S=1  one of D’s results is available A executes wait(S) and enters CS and leaves CS, joins ready queue. 2 B Processor S=0 D C A Ready list Suspended list B executes wait(S) and suspends

35 Example of Semaphore Mechanism* (2/4)
3 D Processor S=-1 B C A Ready list Suspended list D runs; D signals  B moves to ready queue D Processor S=0 C A B Ready list Suspended list 4 D re-joins the ready queue and C executes

36 Example of Semaphore Mechanism* (3/4)
5 C Processor S=0 A B D Ready list Suspended list C issues a wait and is suspended 6 D Processor S=-3 C A B Ready list Suspended list A and B execute and issue wait(S); both are suspended

37 Example of Semaphore Mechanism* (4/4)
D Processor S=-2 A B C Ready list 7 Suspended list D gets its turn ; issues signal(S); wakeups C and C goes to ready list. Later cycles of D will release A and then B.

38 6.6 Semaphores: Deadlock and Starvation
Deadlock (死結) – two or more processes are waiting indefinitely for an event that can be caused by only one of the waiting processes 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 blocked process may never be removed from the list associated with a semaphore in LIFO (last-in, first-out) order P0: wait(S) … pass P1: wait(Q) … pass P0: wait(Q) … block P1: wait(S) … block

39 6.7 Classical Problems of Synchronization
Bounded-buffer problem Readers and writers problem Dining-philosophers problem Examples for a large class of concurrency-control problems Used for testing nearly every newly proposed synchronization scheme Semaphores are used for synchronization

40 6.7 Classical Problems of Synchronization: The Bounded Buffer Problem
To illustrate the power of synchronization primitives Assume the pool consists of n buffers The mutex (initially 1) semaphore provides mutual exclusion The empty (initially n) and full (initially 0) semaphores count the number of empty and full buffers, respectively

41 6.7 Classical Problems of Synchronization: The Bounded Buffer Problem
Producer Consumer do { ... produce an item in nextp wait(empty); wait(mutex); add nextp to buffer signal(mutex); signal(full); } while (1); do { wait(full); wait(mutex); ... remove an item from buffer to nextc signal(mutex); signal(empty); consume the item in nextc } while (1);

42 6.7 Classical Problems of Synchronization: The Readers-Writers Problem
A data object, such as a file or record, is to be shared among several concurrent processes Writers are required to have exclusive access to the shared object 2 problem variants No reader is kept waiting unless a writer has already obtained permission to use the shared object No reader should wait for other readers to finish simply because a writer is waiting. Once a writer is ready, the writer performs its write as soon as possible. If a writer is waiting to access the object, no new readers may start reading 底下將為第一類型的問題探討解決方案

43 readcount (initially 0)
6.7 Classical Problems of Synchronization: A Solution to the 1st Problem — Data Structure readcount (initially 0) A variable that keeps track of how many processes are currently reading the object mutex (initially 1) A semaphore that is used to ensure mutual exclusion when the variable readcount is updated rw_mutex (initially 1) A semaphore that functions as a mutual exclusion semaphore for the writers Also used by the first or last reader that enters or exits the critical section

44 6.7 Classical Problems of Synchronization: A Solution to the 1st Problem
W W R The Reader wait(mutex); readcount ++; if (readcount == 1) wait(rw_mutex); signal(mutex); ... reading is performed readcount --; if (readcount == 0) signal(rw_mutex); The Writer wait(rw_mutex); ... writing is performed signal(rw_mutex); /* The writer may starve */ If a writer is in the critical section and n readers are waiting, then one reader is queued on rw_mutex and n-1 readers are queued on mutex. When a writer executes signal(rw_mutex), we may resume execution of either the waiting readers or a single waiting writer. The selection is made by the scheduler.

45 6.7 Classical Problems of Synchronization: The Dining Philosopher Problem
A philosopher can pick up one chopstick at a time A philosopher can release both chopsticks at the same time Represent each chopstick by a semaphore Shared data: semaphore chopstick[5] //Philosopher i do { wait(chopstick[i]); wait(chopstick[(i+1)%5]); ... // eat signal(chopstick[i]); signal(chopstick[(i+1)%5]); // think } while (true); Deadlock possible: each grabs her left chopstick

46 Remedies to the deadlock problem
6.7 Classical Problems of Synchronization: The Dining Philosopher Problem Remedies to the deadlock problem Allow at most four philosophers to be sitting simultaneously at the table Allow a philosopher to pick up her chopsticks only if both chopsticks are available She must pick up them up in a critical section Use an asymmetric solution An odd philosopher picks up first her left chopstick and then her right chopstick, whereas an even philosopher picks up her right chopstick and then her left chopstick

47 Incorrect use of semaphores may cause timing errors
6.8 Monitors Incorrect use of semaphores may cause timing errors signal(mutex); ... critical section wait(mutex); wait(mutex); ... critical section wait(mutex); ... critical section ... critical section signal(mutex);

48 Another high-level synchronization construct monitor monitor_name
6.8 Monitors Another high-level synchronization construct monitor monitor_name { shared variable declarations procedure body P1 (…) { . . . } procedure body P2 (…) { procedure body Pn (…) { initialization code

49 To allow a process to wait within the monitor
6.8 Monitors To allow a process to wait within the monitor A condition variable must be declared as condition x, y; Condition variable can only be used with the operations wait and signal The operation x.wait(); means that the process invoking this operation is suspended until another process invokes x.signal(); The x.signal operation resumes exactly one suspended process. If no process is suspended, then the signal operation has no effect.

50 6.8 Monitors: With Condition Variables

51 6.8 Monitors: After Signaling a Condition …
Q invokes x.wait()  suspended P invokes x.signal() Signal and wait: P either waits until Q leaves the monitor, or waits for another condition (advocated by Hoare) Signal and continue: Q either waits until P leaves the monitor, or waits for another condition Compromise (折衷方式) When thread P executes the signal operation, it immediately leaves the monitor Hence Q is immediately resumed.

52 6.8 Monitors: Dining Philosophers Example
monitor dp { enum {thinking, hungry, eating} state[5]; condition self[5]; void pickup(int i) void putdown(int i) void test(int i) void init() { for (int i = 0; i < 5; i++) state[i] = thinking; } dp.pickup(i) all you can eat  …. dp.putdown(i) How to call

53 6.8 Monitors: Dining Philosophers Example
void test(int i) { if ((state[(i+4)%5] != eating) && (state[i] == hungry) && (state[(i+1)% 5] != eating)) { state[i] = eating; self[i].signal(); } 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); /* 嘗試把下一位喚醒 */ dp.pickup(i) all you can eat  …. dp.putdown(i) How to call

54 6.9 Synchronization Examples
不列入考試範圍

55 6.10 Alternative Approaches
不列入考試範圍


Download ppt "Chapter 6 Process Synchronization"

Similar presentations


Ads by Google