Title: Process Synchronization
1Process Synchronization
2Chapter 7 Process Synchronization
- Background need for process synchronization
- The Critical-Section Problem protecting
critical only - Synchronization Hardware TestAndSet, Swap
- Semaphores
- Classical Problems of Synchronization
- Conditional Critical Regions
- Monitors
- Synchronization in Solaris 2 Windows 2000
3Semaphores
- Semaphore S an integer variable that is
accessed only through two indivisible (atomic)
operations. - Classical definitions
- Proberen (P, Dutch for test)
- wait (S)
- while S ? 0 do no-op S--
-
- Verhogen (V, Dutch for increment)
- signal (S)
- S
-
4Semaphores
a) Stop
b) All Clear
The semaphore used by railroads indicates whether
the train can proceed. When its lowered (a), an
oncoming train is expected. If it is raised (b),
the train can continue.
5Semaphores
- The classical semaphore is a non-negative integer
that is used as a flag. - In an operating system, a semaphore signals if
and when a resource is free and can be used by
another process. - In a P, test, wait, operation, the flag is
tested - if it is 0 or negative, the calling process
waits - if it is non-negative, the flag is
decremented and the process continues. - In a V, signal, operation, the flag is
incremented.
6Mutual Exclusion with Semaphores
- Shared data
- int mutex 1 // initially mutex 1
- Process Pi do wait(mutex)
critical section - signal(mutex) remainder
section while (1) -
7Mutual Exclusion with Semaphores
int mutex 1
Process 0
Process 1
- do wait(mutex) critical section
- signal(mutex) remainder section
while (1) -
do wait(mutex) critical section
signal(mutex) remainder section
while (1)
8Mutual Exclusion with Semaphores
semaphore mutex 1
Process 0
Process 1
- do P(mutex) critical section
- V(mutex) remainder section while
(1) -
do P(mutex) critical section
V(mutex) remainder section while (1)
- The first process to invoke P on mutex passes,
and the second blocks. When the first invokes
the V operation on mutex, it continues to
execute, thus enabling the second to proceed when
it gets control of the CPU.
9Synchronization with Semaphores
semaphore synch 0
Process 0
Process 1
- action a
- signal(synch) // V
-
wait(synch) // P action b
- Because synch is initialized to zero, Process 0
will act first, then invoke signal(synch) to
permit Process 1 to execute.
10Synchronization with Semaphores
semaphore s1 0 semaphore s2 0
proc_B while(TRUE) // wait for signal
from proc_B P(s1) read(x)
compute B1 write(z) V(s2)
//signal proc_A compute B2
- proc_A
- while(TRUE) compute A1
- write(x)
- V(s1) //signal proc_B compute A2
- // wait for signal from proc_B P(s2)
- read(z)
-
-
- In this case, the semaphore is used to exchange
synchronization signals among processes, as
opposed to solving the strict critical section
problem.
11Semaphore Implementation
- Problem classical definitions use spinlock,
waste CPU time - Define a semaphore as a C struct
- typedef struct
- int value struct process L
semaphore - Assume two simple system calls
- block suspends the process that invokes it.
- wakeup(Proc) resumes the execution of a blocked
process Proc.
12Implementation
- Semaphore operations now defined as
- void wait (semaphore S) S.value--
- if (S.value lt 0)
- add this process to S.L // e.g.
FIFO block() -
-
- void signal (semaphore S)
- S.value
- if (S.value lt 0)
- remove a process Proc from
S.L wakeup(Proc) -
-
- In this case, negative semaphore values are used
to store the number of processes waiting on that
semaphore.
13Deadlock
- Deadlock a set of processes is in a deadlock
state when every process in the set is waiting
for an event that can be caused only by another
process in the set. - semaphore S 1
- semaphore Q 1
- P0 P1
- wait(S) wait(Q)
- wait(Q) wait(S)
- ? ?
- signal(S) signal(Q)
- signal(Q) signal(S)
- If P0 waits on S and P1 waits on Q,
simultaneously, then if P0 waits on Q, it will
wait indefinitely for P1 to signal Q.
14Starvation
- Starvation a single job is prevented from
execution because it is kept waiting for
resources that never become available. - A phenomenon in which some set of processes are
perpetually ignored because their priority is not
as high as that of other processes. - Starvation can occur in CPU scheduling, disk arm
optimization, or any other kind of resource
allocation scenario - wait(S)
- Starvation or indefinite blocking may occur if
we add and remove processes from the list
associated with a semaphore in LIFO order.
15Two Types of Semaphores
- 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. - Can implement a counting semaphore S as a binary
semaphore.
16Synchronization Hardware
- Test and modify the content of a word atomically.
- boolean TestAndSet(boolean target)
- boolean rv target
- target true
- return rv
-
- TestAndSet(m) or TS(m) causes the memory location
m to be written TRUE. - TS itself returns the boolean value of m
17Mutual Exclusion with Test-and-Set
- Shared data boolean lock false
- Process Pi
- do
- while (TestAndSet(lock))
- critical section
- lock false
- remainder section
-
- Mutual exclusion guaranteed by hardware
- Progress some process will go critical
- Bounded waiting fails some process could wait
forever
18Mutual Exclusion with Test-and-Set
- Shared data boolean lock false
P1 do while (TestAndSet(lock)) critical
section lock false remainder section
P0 do while (TestAndSet(lock)) critical
section lock false remainder section
19Mutual Exclusion with Test-and-Set
- Shared data boolean lock false
P0 do while (TS(lock)) critical
section lock false remainder section
P1 do while (TS(lock)) critical
section lock false remainder section
boolean TS(boolean target) boolean rv
target target true return rv
boolean TS(boolean target) boolean rv
target target true return rv
20Binary Semaphore
TestAndSet
Semaphore
semaphore s 1 . . . P(s) ltcritical
sectiongt V(s) . . .
- boolean s FALSE
- . . .
- while TS(s) ltcritical sectiongt
- s FALSE
- . . .
- TestAndSet, TS can directly supply the P, wait,
operation for binary (0, 1) semaphores.
21Counting Semaphore from Binary
struct semaphore binary_semaphore s1
1 binary_semaphore s2 0 int C ltinitial
valuegt
- wait(semaphore S)
- wait(S.s1) S.C--
- if (S.C lt 0)
- signal(S.s1) wait(S.s2)
-
- signal(S.s1)
-
signal(semaphore S) S.C if (S.C lt 0)
signal(S.s2) else signal(S.s1)
- Test this with different initial values of C
22Counting Semaphore from Binary
binary_semaphore s1 1 binary_semaphore s2
0 int C ltinitial valuegt
- wait(semaphore S)
- wait(s1) C--
- if (C lt 0)
- signal(s1) wait(s2)
-
- signal(s1)
-
signal(semaphore S) C if (C lt
0) signal(s2) else signal(s1)
23Counting Semaphore from Binary
binary_semaphore s1 1 binary_semaphore s2
0 int C ltinitial valuegt
- wait(semaphore S)
- wait(s1) C--
- if (C lt 0)
- signal(s1) wait(s2)
-
- signal(s1)
-
signal(semaphore S) C if (C lt
0) signal(s2) else signal(s1)
s1 1, so sets s1 0 goes
Signals s1, waits on s2
If input C gt 0 advances, sets s1 1.
C lt 0, so some proc waiting. Set s2 1.
S1 protected C--
24Counting Semaphore from TS
binary_semaphore hold false binary_semaphore
mutex true int C ltinitial valuegt
- wait(semaphore S)
- while(TS(mutex)) C--
- if (C lt 0)
- mutex FALSE while(TS(hold))
-
- else
- mutex FALSE
-
signal(semaphore S) while(TS(mutex))
C if (C lt 0) while(!hold) hold
FALSE mutex FALSE
Nutt, Operating Systems A Modern Perspective,
1997, p 212.
25Counting Semaphore from TS
binary_semaphore hold false binary_semaphore
mutex true int C ltinitial valuegt
Before waiting on hold, the mutex protecting C
updates is released.
- wait(semaphore S)
- while(TS(mutex)) C--
- if (C lt 0)
- mutex FALSE while(TS(hold))
-
- else
- mutex FALSE
-
A process waiting for the semaphore will be held
here.
26Counting Semaphore from TS
This saves the results of V (signal) operations
until they can be read by a P (wait)
signal(semaphore S) while(TS(mutex))
C if (C lt 0) while(!hold) hold
FALSE mutex FALSE
V sets hold to False when it detects processes
queued on semaphore S
27Classical Problems of Synchronization
- Bounded-Buffer Problem
- Readers and Writers Problem
- Dining-Philosophers Problem
28Bounded-Buffer Problem
- Assume n buffers, each holding one item
- Shared data semaphore full counts full buffers
- semaphore empty counts empty buffers
- semaphore mutexInitiallyfull 0, empty
n, mutex 1
29Bounded Buffer with Semaphores
Producer Process
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)
do produce an item in nextp
wait(empty) wait(mutex) add nextp
to buffer signal(mutex) signal(full)
while (1)
30Bounded Buffer with Semaphores
Producer Process
Consumer Process
Claim a full buffer
do wait(full) wait(mutex) remove
an item from buffer to nextc
signal(mutex) signal(empty) consume the
item in nextc while (1)
do produce an item in nextp
wait(empty) wait(mutex) add nextp
to buffer signal(mutex) signal(full)
while (1)
Claim an empty buffer
Signal an empty buffer
Signal a full buffer
31Bounded Buffer with Mutex
Thread 1
Thread 2
Main(int argc, char argv) thr_create(NULL,
0, consumer) while(1)
mutex_lock(buflock) while (occ
BUFCNT) cond_wait(remdata,buflock)
read in file, add to buffer
if(byteinbufnextadd 0)
mutex_lock(donelock) done 1
mutex_unlock(donelock) cond_signal(adddat
a) mutex_unlock(bufdata) break
nextadd nextadd BUFCNT occ
cond_signal(adddata) mutex_unlock(bufloc
k) thr_join(cons_tar,0,NULL)\
return(0)
void consumer(void arg) while(1)
mutex_lock(buflock) if( !occ done)
mutex_unlock(buflock) break
while(occ 0 !done)
cond_wait(adddata,buflock) read buffer,
write to out file nextrem nextrem
BUFCNT occ- cond_signal(remdata)
mutex_unlock(buflock) thr_exit((void
)0)
32Readers-Writers Problem
- There can be only one writer at a time, but there
can be many simultaneous readers. - Each writer has exclusive access.
- Options
- 1. No reader will be kept waiting if there are
writers waiting readers wait only if a writer
has already obtained access permission. - 2. Writers have priority, start right away,
temporarily blocking readers. -
33Readers-Writers Problem
- Shared datasemaphore mutex protect readcount
updates - semaphore wrt protect exclusion of writers
- int readcount current number of readers
- Initiallymutex 1, wrt 1, readcount 0
-
-
34Readers-Writers Problem 1Writer Process
-
- while(true)
- wait(wrt)
-
- writing is performed
-
- signal(wrt)
- While writing is going on, n readers could be
queued - 1 reader will be queued on wrt and
- n-1 readers are queued on mutex
35Readers-Writers Problem 1Reader Process
- while(true)
- wait(mutex)
- readcount
- if (readcount 1)
- wait(wrt)
- signal(mutex)
-
- reading is performed
-
- wait(mutex)
- readcount--
- if (readcount 0)
- signal(wrt)
- signal(mutex)
These mutexes protect readcount updates
At this signal, a reader or a writer may be
scheduled
36Readers-Writers Problem 2
- First writer obtains a readBlock semaphore, then
blocks on a writeBlock semaphore while the
current readers finish. - Next writer obtains a writePending semaphore,
blocks on readBlock - More writers block at writeBlock
- Any readers block at writePending
- When all writers have completed, readers can then
begin reading.
37Readers-Writers Problem 2
- Reader()
- while(true)
- P(writePending)
- P(readBlock)
- P(mutex1)
- readcount
- if (readCount 1)
- P(writeBlock)
- V(mutex1)
- V(readBlock)
- V(writePending)
- reading is performed
- P(mutex1)
- readcount--
- if (readCount 0)
- V(writeBlock)
- V(mutex1)
-
Writer() while(true)
P(mutex2) writecount if (writecount
1) P(readBlock) V(mutex2)
P(writeBlock) writing is performed V(writ
eBlock) P(mutex2) writeCount-- if
(writeCount 0) V(readBlock) V(mutex2)
38Dining-Philosophers Problem
- Shared data
- semaphore chopstick5
- Initially all values are 1
39Dining-Philosophers Problem
- There is one chopstick between each philosopher.
- When a philosopher is hungry, he takes two
chopsticks and eats until satisfied. - He may pick up only one chopstick at a time.
- He may not take a chopstick from a neighbour if
they are holding a chopstick.
40Dining-Philosophers Solution?
- Represent each chopstick by a semaphore
- semaphore chopsticks5
- Initial value of each element is 1
- Wait(chopstickn) to try to obtain chopstick n
- Signal(chopstickn) to try to put down
chopstick n
41Dining-Philosophers Solution?
- Philosopher i
- do
- wait(chopsticki)
- wait(chopstick(i1) 5)
-
- eat
-
- signal(chopsticki)
- signal(chopstick(i1) 5)
-
- think
-
- while (1)
42Dining-Philosophers Solution?
- However, if all five philosophers take their left
chopstick, then all semaphores are 0, and there
is deadlock. - Remedies
- Remove one philosopher
- Check to see if both chopsticks are available,
then pick them up - Use asymmetry odd philosophers pick up left
first, while even philosophers pick up right
first - But will a philosopher starve?