Chapter 7: Process Synchronization
Chapter 7: Process Synchronization
Background
The Critical-Section Problem
Synchronization Hardware
Semaphores
Classical Problems of Synchronization
Critical Regions
Monitors
Synchronization in Solaris 2 & Windows 2000
#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 Pi can enter its critical section
Process Pi
do {
while (turn != i) ;
critical section
turn = j;
reminder section
} while (1);
Satisfies mutual exclusion, but not progress
Shared variables
boolean flag[2];
initially flag [0] = flag [1] = false.
flag [i] = true Pi ready to enter its critical section
Process Pi
do {
flag[i] := true;
while (flag[j]) ; critical section
flag [i] = false;
remainder section
} while (1);
Satisfies mutual exclusion, but not progress requirement.
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);
return rv;
}
Shared data:
boolean lock = false;
Process Pi
do {
while (TestAndSet(lock)) ;
critical section
lock = false;
remainder section
}
Process Pi
do {
key = true;
while (key == true)
Swap(lock,key);
critical section
lock = false;
remainder section
}
signal (S):
S++;
Shared data:
semaphore mutex; //initially mutex = 1
Process Pi:
do {
wait(mutex);
critical section
signal(mutex);
remainder section
} while (1);
signal(S):
S.value++;
if (S.value <= 0) {
remove a process P from S.L;
wakeup(P);
}
Data structures:
binary-semaphore S1, S2;
int C:
Initialization:
S1 = 1
S2 = 0
C = initial value of semaphore S
signal operation
wait(S1);
C ++;
if (C <= 0)
signal(S2);
else
signal(S1);
Bounded-Buffer Problem
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(rt);
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);
}
x-count++;
if (next-count > 0)
signal(next);
else
signal(mutex);
wait(x-sem);
x-count--;
if (x-count > 0) {
next-count++;
signal(x-sem);
wait(next);
next-count--;
}