Module 7: Process Synchronization

Download Report

Transcript Module 7: Process Synchronization

Background
 Shared-memory solution to bounded-buffer problem
allows at most n – 1 items in buffer at the same time.
 A solution, where all N buffers are used is not simple.
 Suppose that we modify the producer-consumer code by
adding a variable counter, initialized to 0 and incremented
each time a new item is added to the buffer
 Shared data
#define BUFFER_SIZE 10
typedef struct {
. . .
} item;
item buffer[BUFFER_SIZE];
int in = 0;
int out = 0;
int counter = 0;
Operating System Concepts
7.1
Silberschatz, Galvin and Gagne 2002
Bounded-Buffer Attempt
 Producer process
while (1) {
while (counter == BUFFER_SIZE)
; /* do nothing */
buffer[in] = nextProduced;
in = (in + 1) % BUFFER_SIZE;
counter++;
}
 Consumer process
while (1) {
while (counter == 0)
; /* do nothing */
nextConsumed = buffer[out];
out = (out + 1) % BUFFER_SIZE;
counter--;
}
Operating System Concepts
7.2
Silberschatz, Galvin and Gagne 2002
Bounded Buffer
 The statement counter++ may be implemented in
machine language as:
register1 = counter
register1 = register1 + 1
counter = register1
 The statement counter-- may be implemented as:
register2 = counter
register2 = register2 – 1
counter = register2
 If both the producer and consumer attempt to update the
counter concurrently, the assembly language statements
may get interleaved.
Operating System Concepts
7.3
Silberschatz, Galvin and Gagne 2002
Bounded Buffer
 Assume counter is initially 5. One interleaving of
statements is:
producer:
producer:
consumer:
consumer:
producer:
consumer:
register1
register1
register2
register2
counter =
counter =
= counter
= register1 + 1
= counter
= register2 – 1
register1
register2
(register1 = 5)
(register1 = 6)
(register2 = 5)
(register2 = 4)
(counter = 6)
(counter = 4)
 The value of counter may be either 4 or 6, where the
correct result should be 5.
 Interleaving depends upon how the producer and
consumer processes are scheduled.
 The statements counter++; and counter--; must be
performed atomically.
 Atomic operation means an operation that completes in its
entirety without interruption.
Operating System Concepts
7.4
Silberschatz, Galvin and Gagne 2002
Race Condition
 Concurrent access to shared data may result in data




Operating System Concepts
inconsistency.
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.
The concurrent processes have critical sections, in
which they modify shared data
A limited number of processes can be in their critical
sections at the same time.
7.5
Silberschatz, Galvin and Gagne 2002
The Critical-Section Problem
 N processes all competing to use some shared data
 Each process has a code segment, called critical section,
in which the shared data is accessed.
 Problem – ensure that maximally R (often R = 1)
processes executing in their critical section.
 General structure of process Pi
do {
entry section
critical section
exit section
remainder section
} while (1);
Operating System Concepts
7.6
Silberschatz, Galvin and Gagne 2002
Solution to Critical Section Problem
 Requirements
1. Mutual Exclusion - Maximally R processes in their critical section
2. Progress - If less than R processes are in their critical sections,
then a process that wishes to enter it critical section is not delayed
indefinitely.
3. Bounded Waiting - Only a bounded amount of “overtaking” into
critical sections is permitted.
 Assumptions
 Assume that each process executes at a non-zero speed
 No assumption concerning relative speed of the processes.
 Atomic execution of machine code instructions (think of the fetchinterrupt?-decode-execute cycle)
 Types of solutions
 Software - no hardware support but slow
 Hardware supported
Operating System Concepts
7.7
Silberschatz, Galvin and Gagne 2002
2 Processes, 1 at-a-time, Algorithm 1
 Processes P0 and P1
 Shared variables:
 int turn = 0;
 turn = i  Pi can enter its critical section
 Process Pi
do {
while (turn != i)
;
critical section
turn = 1 - i;
reminder section
} while (1);
 Satisfies mutual exclusion, but not progress
 A process can be stuck in its remainder
 Problem is forced alternation
Operating System Concepts
7.8
Silberschatz, Galvin and Gagne 2002
2 Processes, 1 at-a-time, Algorithm 2
 Shared variables
 boolean flag[2] = {false,false};
 flag[i] = true  Pi ready to enter its critical section
 Process Pi
do {
flag[i] := true;
while (flag[1-i])
;
critical section
flag[i] = false;
remainder section
} while (1);
 Satisfies mutual exclusion, but not progress
 Both can set flag[i] before proceeding
 Switching the first two lines violates mutual exclusion
Operating System Concepts
7.9
Silberschatz, Galvin and Gagne 2002
2 Processes, 1 at-a-time, Algorithm 3
(Peterson’s Algorithm)
 Combined shared variables of algorithms 1 and 2.
 Process Pi
do {
flag[i]:= true;
//----I’m ready
turn = 1-i;
//----It’s your turn (last RAM access)
while (flag[1-i] and turn == 1-i)
; //----Wait if other is ready and it’s its turn
critical section
flag[i] = false; //----I’m not ready any more
remainder section
} while (1);
 Meets all three requirements; solves the critical-section problem
for two processes.
Operating System Concepts
7.10
Silberschatz, Galvin and Gagne 2002
N Processes, 1 at-a-time,
Bakery Algorithm
 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.
 Numbers are handed out in non-decreasing order, e.g.,
1,2,3,3,3,3,4,5...
 Notation < lexicographical order (ticket #, process id #)
 (a,b) < (c,d) if a < c or if a = c and b < d
Operating System Concepts
7.11
Silberschatz, Galvin and Gagne 2002
Bakery Algorithm
 Shared data
boolean choosing[n] = {false*};
int number[n] = {0*};
 Algorithm for 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])
; //---Wait for a process that is getting a number
while (number[j] != 0 && (number[j],j) < (number[i],i))
; //---Wait for process with better numbers
}
critical section
number[i] = 0; //---Release the number and interest
remainder section
} while (1);
Operating System Concepts
7.12
Silberschatz, Galvin and Gagne 2002
Hardware Supported Solutions
 Turn off interrupts
 Affects multi-tasking - too dangerous
 Affects clock
 Affects critical OS activities
 Atomically swap two variables.
void Swap(boolean &a, boolean &b) {
boolean temp = a;
a = b;
b = temp;
}
 Test and modify the content of a word atomically
boolean TestAndSet(boolean &target) {
boolean return_value = target;
target = true;
return(return_value);
}
Operating System Concepts
7.13
Silberschatz, Galvin and Gagne 2002
N Processes, 1 at-a-time, Using swap
 Shared data
boolean lock = false;
//----Nobody using
 Local data
boolean key;
 Process Pi
do {
key = true; //---I want in
while (key) //---Wait until free
Swap(lock,key);
critical section
lock = false;
//---Set it free
remainder section
}
 Does not satisfy bounded wait
Operating System Concepts
7.14
Silberschatz, Galvin and Gagne 2002
N Processes, 1 at-a-time, Using T&S
 Shared data:
boolean lock = false;
 Process Pi
do {
while (TestAndSet(lock))
;
critical section
lock = false;
remainder section
}
 Does not satisfy bounded wait
Operating System Concepts
7.15
Silberschatz, Galvin and Gagne 2002
N Processes, 1 at-a-time, Using T&S
 Shared data
boolean waiting[0..n-1] = {false*};
boolean lock = false;
 Algorithm for Pi
while (1) {
waiting[i] = true; //---I want in
key = true; //---Assume another is in C.S.
while (waiting[i] && key)
key = TestAndSet(lock); //---Busy wait
waiting[i] = false
critical section
j = (i+1) % n; //---Look to see who’s waiting
while (j != i && !waiting[j])
j = (j+1) % n;
if (j == i) then
lock = false; //----No one
else waiting[j] = false;
//---Someone
remainder section
} (see Geoff’s example)
Operating System Concepts
7.16
Silberschatz, Galvin and Gagne 2002
Semaphores
 Working towards a synchronization tool that does not
require busy waiting.
 Semaphore S – integer variable
 Can only be accessed via two atomic operations
wait(S):
//---P(S)
when S > 0 do
S--;
signal(S):
S++;
Operating System Concepts
//----V(S)
7.17
Silberschatz, Galvin and Gagne 2002
N Processes, R at-a-time, Using Semaphores
 Shared data:
semaphore mutex = R;
//----R processes in parallel
 Process Pi:
do {
wait(mutex);
critical section
signal(mutex);
remainder section
} while (1);
Operating System Concepts
7.18
Silberschatz, Galvin and Gagne 2002
Semaphore as a General Synchronization Tool
 Execute B in Pj only after A executed in Pi
 Use semaphore flag initialized to 0
 Code:
Pi

A
signal(flag)
Operating System Concepts
Pj

wait(flag)
B
7.19
Silberschatz, Galvin and Gagne 2002
Implementing Semaphores
 How to implement wait?
wait(S):
while (S <= 0) //---Busy wait
;
S--;
//---Not atomic?
 How to implement signal?
signal(S):
S++;
//---Not atomic?
Operating System Concepts
7.20
Silberschatz, Galvin and Gagne 2002
Spinlock Binary Semaphore Implementation
 Spinlock binary semaphores implemented with T&S
 B = FALSE means B = 1
 B = TRUE means B = 0
wait(B):
while (TestAndSet(B))
;
signal(B):
B = false;
 Note the busy wait in wait(B)
 Will be avoided in general semaphore implementation
 When used for CS problem, bounded-wait is violated
because while is not indivisible
 However, useful in some situations
Operating System Concepts
7.21
Silberschatz, Galvin and Gagne 2002
Spinlock Semaphore Implementation
 Data structures:
binary-semaphore B1=1, B2=0;
int C = R;
 When C is less than 0 the semaphore value is 0.
 wait operation
wait(B1);
C--;
if (C < 0) {
signal(B1);
wait(B2);
}
signal(B1);
//---Mutex on C
//---Have to stop here
//---Busy wait
 signal operation
wait(B1);
C++;
if (C <= 0)
signal(B2);
else signal(B1);
Operating System Concepts
7.22
Silberschatz, Galvin and Gagne 2002
Semaphore Implementation
 Assume two simple operations:
 block(P) moves P to the waiting state, with the PCB linked
into the semaphore list
 wakeup(P) moves P to the ready state
Operating System Concepts
7.23
Silberschatz, Galvin and Gagne 2002
Semaphore Implementation
wait(P,S):
wait(B1) //---Short busy wait
C-if (C < 0)
block(P);
signal(B1)
signal(P,S):
wait(B1) //---Short busy wait
C++
if (C <= 0)
wakeup(Someone)
//---“when” and S-signal(B1)
 When C is less than 0 the semaphore value is 0.
Operating System Concepts
7.24
Silberschatz, Galvin and Gagne 2002
Semaphore Implementation Expanded
wait(P,S):
while (TestAndSet(B1))
;
C-if (C < 0)
block(P);
B1 = FALSE
signal(P,S):
while (TestAndSet(B1))
;
C++
if (C <= 0)
wakeup(Someone)
B1 = FALSE
Operating System Concepts
7.25
Silberschatz, Galvin and Gagne 2002
Bounded-Buffer Problem
 Shared data
semaphore full = 0, empty = R, mutex = 1;
 Producer Process
do {
produce an item in nextp
wait(empty);
wait(mutex);
add nextp to buffer
signal(mutex);
signal(full);
} while (1);
 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);
Operating System Concepts
7.26
Silberschatz, Galvin and Gagne 2002
Readers-Writers Problem 1
 Shared data
semaphore mutex = 1, wrt = 1;
int readcount = 0; //---Number of readers in action
 Writer Process
wait(wrt);
writing is performed
signal(wrt);
 Reader Process
wait(mutex); //---Mutex on readcount
readcount++;
if (readcount == 1) //---First reader
wait(wrt);
//---Wait to lock out writers
signal(mutex);
reading is performed
wait(mutex);
readcount--;
if (readcount == 0) //---Last reader
signal(wrt);
//---Allow writers
signal(mutex):
Operating System Concepts
7.27
Silberschatz, Galvin and Gagne 2002
Dining-Philosophers Problem
 Shared data
semaphore chopstick[N] = {1*};
 Philosopher i:
do {
wait(chopstick[i]);
wait(chopstick[(i+1) % N]);
eat;
signal(chopstick[i]);
signal(chopstick[(i+1) % N]);
think;
} while (1);
 Leads to deadlock
 Limit philosophers
 Pickup both at once
 Asymmetric pickup
Operating System Concepts
7.28
Silberschatz, Galvin and Gagne 2002
Critical Regions
 High-level synchronization construct
 A shared variable v of type T, is declared as:
v: shared T
 Variable v accessed only inside statement
region v when B do S;
where B is a boolean expression.
 Only one process can be in a region at a time.
 When a process executes the region statement, B is
evaluated.
 If B is true, statement S is executed.
 If B is false, the process is queued until no process is in the
region associated with v, and B is tested again
Operating System Concepts
7.29
Silberschatz, Galvin and Gagne 2002
Example – Bounded Buffer
 Shared data:
buffer : shared struct {
int pool[n];
int count, in, out;
}
 Producer
region buffer when (count < n) do {
pool[in] = nextp;
in:= (in+1) % n;
count++;
}
 Consumer
region buffer when (count > 0) do {
nextc = pool[out];
out = (out+1) % n;
count--;
}
Operating System Concepts
7.30
Silberschatz, Galvin and Gagne 2002
Monitors
 High-level synchronization construct that allows the safe sharing
of an abstract data type among concurrent processes.
monitor monitor-name {
shared variable declarations
procedure body P1 (…) {
. . . //---Can access shared vars and params
}
procedure body P2 (…) {
. . .
}
procedure body Pn (…) {
. . .
}
{
initialization code
}
}
 Only one process can be executing in a monitor at a time
Operating System Concepts
7.31
Silberschatz, Galvin and Gagne 2002
Schematic View of a Monitor
Operating System Concepts
7.32
Silberschatz, Galvin and Gagne 2002
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.
 Hmmm, which runs, signaller or signalled? Compromise signaller must exit the monitor
Operating System Concepts
7.33
Silberschatz, Galvin and Gagne 2002
Monitor With Condition Variables
Operating System Concepts
7.34
Silberschatz, Galvin and Gagne 2002
Dining Philosophers Example
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((i+4) % 5);
test((i+1) % 5);
}
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 init() {
for (int i = 0; i < 5; i++)
state[i] = thinking;
}
}
Operating System Concepts
7.35
Silberschatz, Galvin and Gagne 2002