1 Process Synchronization
1 Process Synchronization
Process Synchronization
Background
The Critical-Section Problem
Peterson’s Solution
Synchronization Hardware
Semaphores
Classic Problems of Synchronization
Objectives
After the above two statements, the value of the counter may be 4,
5, or 6.
The only correct result is counter ==5, which is generated correctly
if the producer and consumer execute separately.
Producer
while (true) {
while (true) {
while (counter == 0)
; // do nothing
nextConsumed = buffer[out];
out = (out + 1) % BUFFER_SIZE;
counter--;
register1 = counter
register1 = register1 + 1
counter = register1
counter-- could be implemented in machine language as:
register2 = counter
register2 = register2 - 1
counter = register2
Consider this execution interleaving with “counter = 5” initially:
T0: producer execute register1 = counter {register1 = 5}
T1: producer execute register1 = register1 + 1 {register1 = 6}
T2: consumer execute register2 = counter {register2 = 5}
T3: consumer execute register2 = register2 - 1 {register2 = 4}
T4: producer execute counter = register1 {counter = 6 }
T5: consumer execute counter = register2 {counter = 4}
• Now we have arrived at the incorrect state “counter ==4”
Race Condition
If we reversed the order of the statements at T 4 and T5 we would
arrive at the incorrect state “counter==6”.
Provable that
1. Mutual exclusion is preserved
2. Progress requirement is satisfied
3. Bounded-waiting requirement is met
Synchronization Hardware
Many systems provide hardware support for critical section
code
do {
acquire lock
critical section
release lock
remainder section
} while (TRUE);
Semaphore
Synchronization tool
Semaphore S – integer variable
Two standard operations modify S: wait() and signal()
Originally called P() (“to test”) and V() (“to increment”)
Less complicated
Can only be accessed via two atomic operations
wait (S) {
while S <= 0
; // no-op
S--;
}
signal (S) {
S++;
}
Semaphore 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
We can implement a counting semaphore S as a binary semaphore
Provides mutual exclusion among multiple processes
Suppose n processes share a semaphore, mutex, initialized to 1. Here, each process
Pi is organized as below:
Semaphore mutex; // initialized to 1
do {
wait (mutex);
// Critical Section
signal (mutex);
// remainder section
} while (TRUE);
Semaphore as General Synchronization Tool
Implementation of wait:
wait(semaphore *S) {
S->value--;
if (S->value < 0) {
add this process to S->list;
block();
}
}
Implementation of signal:
signal(semaphore *S) {
S->value++;
if (S->value <= 0) {
remove a process P from S->list;
wakeup(P);
}
}
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 process may never be removed from the semaphore queue in
which it is suspended
Classical Problems of Synchronization
Bounded-Buffer Problem
Dining-Philosophers Problem
Bounded-Buffer Problem
N buffers, each can hold one item
do {
………..
// produce an item in nextp
………..
wait (empty);
wait (mutex);
………….
// add the item to the buffer
………….
signal (mutex);
signal (full);
} while (TRUE);
Bounded Buffer Problem (Cont.)
The structure of the consumer process
do {
wait (full);
wait (mutex);
…………
// remove an item from buffer to nextc
…………
signal (mutex);
signal (empty);
………….
// consume the item in nextc
…………
} while (TRUE);
Readers-Writers Problem
A database 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
Shared Data
Database
Semaphore mutex initialized to 1
Semaphore wrt initialized to 1
Integer readcount initialized to 0
Readers-Writers Problem Variations
First variation – no reader will be kept waiting unless a writer has
already obtained permission to use the shared object. In other
words, no reader should wait for other readers to finish simply
because a writer is waiting.
Second variation – once a writer is ready, it performs write as soon
as possible. In other words, if a writer is waiting to access the
object, no new readers may start reading.
Both may have starvation. In first, writers may starve; in second,
readers may starve, leading to even more variations.
Problem is solved on some systems by kernel providing reader-writer
locks.
Here we present a solution to the first variation.
Readers-Writers Problem (Cont.)
The structure of a writer process
do {
wait (wrt) ;
………..
// writing is performed
…………
signal (wrt) ;
} while (TRUE);
Readers-Writers Problem (Cont.)
The structure of a reader process
do {
wait (mutex) ;
readcount ++ ;
if (readcount == 1)
wait (wrt) ;
signal (mutex)
………….
// reading is performed
………….
wait (mutex) ;
readcount - - ;
if (readcount == 0)
signal (wrt) ;
signal (mutex) ;
} while (TRUE);
Dining-Philosophers Problem
do {
wait ( chopstick[i] );
wait ( chopStick[ (i + 1) % 5] );
// eat
signal ( chopstick[i] );
signal (chopstick[ (i + 1) % 5] );
// think
} while (TRUE);