Process Synchronization
Process Synchronization
Operating Systems
● Shared data
var n;
type item = ….;
var buffer: array[0..n-1] of item;
in, out: 0..n-1;
in :=0; out:= 0; /* shared buffer = circular array */
/* Buffer empty if in == out */
/* Buffer full if (in+1) mod n == out */
/* noop means ‘do nothing’ */
Bounded Buffer - Shared
Memory Solution
● Consider this execution interleaving with “count = 5” initially (we expect count = 5 in
the end too):
S0: producer execute register1 = counter {register1 = 5}
S1: producer execute register1 = register1 + 1 {register1 = 6}
S2: consumer execute register2 = counter {register2 = 5}
S3: consumer execute register2 = register2 – 1 {register2 = 4}
S4: producer execute counter = register1 {counter = 6 }
S5: consumer execute counter = register2 {counter = 4 !!}
● Mutual Exclusion
• If process Pi is executing in its critical section, then no other
processes can be executing in their critical sections.
● Progress
• If no process is executing in its critical section and there exists
some processes that wish to enter their critical section, then
the selection of the processes that will enter the critical section
next cannot be postponed indefinitely.
● Bounded Waiting
• A bound must exist on the number of times that other
processes are allowed to enter their critical sections after a
process has made a request to enter its critical section and
before that request is granted.
Principles of Operating Systems -
Process Synchronization 16
Solution: Critical Section
Problem - Requirements
● Shared Variables:
● var turn: (0..1);
initially turn = 0;
● turn = i Pi can enter its critical section
● Process Pi
repeat
while turn <> i do no-op;
critical section
turn := j;
remainder section
until false
Satisfies mutual exclusion, but not progress.
22
Algorithm 3
● Shared Variables
● var flag: array (0..1) of boolean;
initially flag[0] = flag[1] = false;
● flag[i] = true Pi ready to enter its critical section
● Process Pi
repeat
while flag[j] do no-op;
flag[i] := true;
critical section
flag[i]:= false;
remainder section
until false
24
24
Algorithm 4
● Combined Shared Variables of algorithms 1 and 2
● Process Pi
repeat
flag[i] := true;
turn := j;
while (flag[j] and turn=j) do no-op;
critical section
flag[i]:= false;
remainder section
until false
YES!!! Meets all three requirements, solves the critical section
problem for 2 processes.
Also called “Peterson’s solution”
● Notation -
● Lexicographic order(ticket#, process id#)
● (a,b) < (c,d) if (a<c) or if ((a=c) and (b < d))
● max(a0,….an-1) is a number, k, such that k >=ai
for i = 0,…,n-1
● Shared Data
var choosing: array[0..n-1] of boolean;(initialized to false)
number: array[0..n-1] of integer; (initialized to 0)
Higher-level
Locks Semaphores Monitors Send/Receive CCregions
API
waiting [i ] := false;
critical section
j := i+1 mod n;
while (j <> i ) and (not waiting[j]) do j := j + 1 mod n;
if j = i then lock := false;
else waiting[j] := false;
remainder section
until false;
36
acquire() and release()
Semantics of acquire
● acquire(mutex_lock) {
while Test&Set(mutex_lock)) ; /* busy wait */
}
●Semantics of release
● release(mutex_lock) {
mutex_lock = 0;
}
●Critical section implementation
do {
acquire (lock)
critical section
release (lock)
remainder section
} while (true);
37
Semaphore
● Semaphore S - integer variable (non-negative)
• used to represent number of abstract resources
● Can only be accessed via two indivisible (atomic) operations
wait (S): while S <= 0 do no-op
S := S-1;
signal (S): S := S+1;
• P or wait used to acquire a resource, waits for semaphore to
become positive, then decrements it by 1
• V or signal releases a resource and increments the semaphore
by 1, waking up a waiting P, if any
• If P is performed on a count <= 0, process must wait for V or
the release of a resource.
P():“proberen” (to test) ; V() “verhogen” (to increment) in Dutch
● Shared variables
var mutex: semaphore
initially mutex = 1
● Process Pi
repeat
wait(mutex);
critical section
signal (mutex);
remainder section
until false
● Shared data
type item = ….;
var buffer: array[0..n-1] of item;
full, empty, mutex : semaphore;
nextp, nextc :item;
full := 0; empty := n; mutex := 1;
● ASymmetry?
● Producer does: P(empty), V(full)
● Consumer does: P(full), V(empty)
● Is order of P’s important?
● Yes! Can cause deadlock
● Is order of V’s important?
● No, except that it might affect scheduling efficiency
R
R
R
● Shared Data
var mutex, wrt: semaphore (=1);
readcount: integer (= 0);
● Writer Process
wait(wrt);
…
writing is performed
...
signal(wrt);
● Reader process
wait(mutex);
readcount := readcount +1;
if readcount = 1 then wait(wrt);
signal(mutex);
...
reading is performed
...
wait(mutex);
readcount := readcount - 1;
if readcount = 0 then signal(wrt);
signal(mutex);
Shared Data
var chopstick: array [0..4] of semaphore (=1 initially);
● Shared variables
var buffer: shared record
pool:array[0..n-1] of item;
count,in,out: integer;
end;
● Producer Process inserts nextp into the shared buffer
region buffer when count < n
do begin
pool[in] := nextp;
in := in+1 mod n;
count := count + 1;
end;
begin
for i := 0 to 4
do state[i] := thinking;
end;
● Data Structures
var S1 : binary-semaphore;
S2 : binary-semaphore;
S3 : binary-semaphore;
C: integer;
● Initialization
S1 = S3 =1;
S2 = 0;
C = initial value of semaphore S;
● Region x when B do S
var mutex, first-delay, second-delay: semaphore;
first-count, second-count: integer;
● Mutually exclusive access to the critical section
is provided by mutex.
If a process cannot enter the critical section because the
Boolean expression B is false,
it initially waits on the first-delay semaphore;
moved to the second-delay semaphore before it is allowed to
reevaluate B.