L11-Process Synchronization
L11-Process Synchronization
Background
The Critical-Section Problem
Synchronization Hardware
Semaphores
Classical Problems of Synchronization
Critical Regions
Monitors
#define BUFFER_SIZE 10
typedef struct {
...
} item;
item buffer[BUFFER_SIZE];
int in = 0;
int out = 0;
int counter = 0;
Producer process
item nextProduced;
while (1) {
while (counter == BUFFER_SIZE)
; /* do nothing */
buffer[in] = nextProduced;
in = (in + 1) % BUFFER_SIZE;
counter++;
}
Consumer process
item nextConsumed;
while (1) {
while (counter == 0)
; /* do nothing */
nextConsumed = buffer[out];
out = (out + 1) % BUFFER_SIZE;
counter--;
}
The statements
counter++;
counter--;
register1 = counter
register1 = register1 + 1
counter = register1
register2 = counter
register2 = register2 – 1
counter = register2
Shared variables:
int turn;
initially turn = 0
Turn = i P can enter its critical section
i
Process P
i
do {
while (turn != i) ;
critical section
turn = j;
remainder section
} while (1);
Satisfies mutual exclusion
Shared variables
boolean flag[2];
initially flag [0] = flag [1] = false.
flag [i] = true P ready to enter its critical
i
section
Process P
i
do {
flag[i] := true;
while (flag[j]) ;
critical section
flag [i] = false;
remainder section
} while (1);
Satisfies mutual exclusion
Process Pi
do {
while (TestAndSet(&lock))
; // do-nothing
//critical section
lock = false;
//remainder section
}while(1);
// critical section
lock = FALSE;
// remainder section
} while ( TRUE);
Synchronization tool
Semaphore S – integer variable
Two standard operations modify S: wait() and
signal()
Originally called P() [to test] and V() [to
increment] respectively
Can only be accessed via two indivisible
(atomic) operations
wait (S) {
while S <= 0
; // no-op
S--;
}
signal (S) {
S++;
Operating System Concepts
} 7.23 Silberschatz, Galvin and Gagne 2002
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
Provides mutual exclusion
Semaphore S; // initialized to 1
wait (S);
Critical Section
signal (S);
Shared data:
semaphore mutex; //initially mutex = 1
Process Pi:
do {
wait(mutex);
critical section
signal(mutex);
remainder section
} while (1);
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.
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); }
}
Dining-Philosophers Problem
Shared data
Initially:
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);
Shared data
Initially
wait(wrt);
…
writing is performed
…
signal(wrt);
wait(mutex);
readcount++;
if (readcount == 1)
wait(wrt);
signal(mutex);
…
reading is performed
…
wait(mutex);
readcount--;
if (readcount == 0)
signal(wrt);
signal(mutex);
Shared data
semaphore chopstick[5];
Initially all values are 1
Philosopher i:
do {
wait(chopstick[i])
wait(chopstick[(i+1) % 5])
…
eat
…
signal(chopstick[i]);
signal(chopstick[(i+1) % 5]);
…
think
…
} while (1);
Shared data:
struct buffer {
int pool[n];
int count, in, out;
}
monitor monitor-name
{
shared variable declarations
procedure body P1 (…) {
...
}
procedure body P2 (…) {
...
}
procedure body Pn (…) {
...
}
{
initialization code
}
}
void putdown(int i) {
state[i] = thinking;
// test left and right neighbors
test((i+4) % 5);
test((i+1) % 5);
}