Title: Chapter 6 Process Synchronization Part I: Basics
1Chapter 6 Process SynchronizationPart I Basics
2Outline
- Background
- The Critical-Section Problem
- Synchronization Hardware
- Semaphores
3Background
- Concurrent access to shared data may result in
data inconsistency. - Maintaining data consistency requires mechanisms
to ensure the orderly execution of cooperating
processes. - Shared-memory solution to bounded-buffer problem
allows at most n 1 items in buffer at the same
time. A solution where all n buffers are used
is - Suppose that we modify the producer-consumer code
by adding a variable counter, initialized to 0
and incremented each time a new item is added to
the buffer
4Bounded-Buffer
- Shared data
- define BUFFER_SIZE 10
- typedef struct
- . . .
- item
- item bufferBUFFER_SIZE
- int in 0
- int out 0
- int counter 0
5Bounded-Buffer
- Producer process
- item nextProduced
- while (1)
- while (counter BUFFER_SIZE)
- / do nothing /
- bufferin nextProduced
- in (in 1) BUFFER_SIZE
- counter
-
6Bounded-Buffer
- Consumer process
- item nextConsumed
- while (1)
- while (counter 0)
- / do nothing /
- nextConsumed bufferout
- out (out 1) BUFFER_SIZE
- counter--
-
7Bounded Buffer
- The statementscountercounter--must be
performed atomically. - Atomic operation means an operation that
completes in its entirety without interruption.
8Bounded Buffer
- The statement count may be implemented in
machine language asregister1 counter - register1 register1 1counter register1
- The statement count-- may be implemented
asregister2 counterregister2 register2
1counter register2
9Bounded Buffer
- If both the producer and consumer attempt to
update the buffer concurrently, the assembly
language statements may get interleaved. - Interleaving depends upon how the producer and
consumer processes are scheduled.
10Bounded Buffer
- Assume counter is initially 5. One interleaving
of statements (race condition) is - producer register1 counter (register1 5)
- producer register1 register1 1 (register1
6) - consumer register2 counter (register2 5)
- consumer register2 register2 1 (register2
4) - producer counter register1 (counter 6)
- consumer counter register2 (counter 4)
- The value of counter may be either 4 or 6, where
the correct result should be 5.
11Race Condition
- Race condition The situation where several
processes access and manipulate shared data
concurrently. The final value of the shared data
depends upon which process finishes last. - To prevent race conditions, concurrent processes
must be synchronized.
12The Critical-Section Problem
- n processes all competing to use some shared data
- Each process has a code segment, called critical
section, in which the shared data is accessed. - Problem ensure that when one process is
executing in its critical section, no other
process is allowed to execute in its critical
section.
13Solution to Critical-Section Problem
- 1. 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 CS
and there exist some processes that wish to enter
their CS, then - (1) only those not in RS can participate the
decision of the next, and - (2) this selection cannot be postponed
indefinitely. - 3. Bounded Waiting. A bound must exist on the
number of times that other processes are allowed
to enter their CSs after a process has made a
request to enter its CS and before that request
is granted. - Assume that each process executes at a nonzero
speed. - No assumption concerning relative speed of the n
processes.
14Initial Attempts to Solve Problem
- Only 2 processes, P0 and P1
- General structure of process Pi (other process
Pj) - do
- entry section
- critical section
- exit section
- reminder section
- while (1)
15Algorithm 1
- Shared variables
- int turninitially 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
- Executing sequence Pi, Pj, Pi, Pj, Pi, Pj,
16Algorithm 2 (1)
- Shared variables
- boolean flag2initially flag 0 flag 1
false. - flag i true ? Pi ready to enter its critical
section - Process Pi
- do
- flagi true while (flagj)
- critical section
- flag i false
- remainder section
- while (1)
- Satisfies mutual exclusion, but not progress
requirement.
17Algorithm 2 (2)
- May loop infinitely
- If changes the order to be
- while (flagj)
- flagi true
- then the condition of mutual exclusion will not
hold.
18Algorithm 3 A correct solution
- Combined shared variables of algorithms 1 and 2.
- Process Pi
- do / Petersons solution
- flag i true turn j while (flag j
and turn j) - critical section
- flag i false
- remainder section
- while (1)
- turn will be set for both i and j
simultaneously, but only one (turn i) or (turn
j) will last. - Meets all three requirements solves the
critical-section problem for two processes.
19Algorithm 3 (2)
- mutual exclusion
- At the moment that Pi enters its CS ?
- flagi true
- either flagj false, or flagj true and
turn i - If flagj false, (later if Pj waits to enter)
- (flagi true turn i) prevents Pj from
entering its CS until Pi exits - If flagj true and turn i, the same
- progress
- suppose Pi wishes to enter CS
- if flagj false, Pi can enter
- otherwise, turn allows either Pi or Pj to enter
- bounded waiting at most one entry of Pj
20Bakery Algorithm Critical section for n processes
- Before entering its critical section, process
receives a number. Holder of the smallest number
enters the critical section. - If processes Pi and Pj receive the same number,
if i lt j, then Pi is served first else Pj is
served first. - The numbering scheme always generates numbers in
increasing order of enumeration i.e.,
1,2,3,3,3,3,4,5...
21Bakery Algorithm (2)
- Notation
- lexicographical order (ticket , process id )
- (a, b) lt (c, d) if a lt c or if a c and b lt d
- max (a0,, an-1)
- Shared data
- boolean choosingn
- int numbern
- initialized to false and 0, respectively.
22Bakery Algorithm (3)
- do
- choosingi true
- numberi max(number0, number1, , number
n 1)1 - choosingi false
- for (j 0 j lt n j)
- while (choosingj) / Wait for the choosing
of Pj - while ((numberj ! 0) (numberj,j) lt
numberi, i)) / smallest first -
- critical section
- numberi 0
- remainder section
- while (1)
23Bakery Algorithm (4)
- Key for showing the correctness
- if Pi in CS, all other Pk has
- numberk 0, or
- (numberi, i) lt (numberk, k)
- mutual exclusion OK
- progress OK (smallest first)
- bounded waiting OK
- Note that processes enter their CSs in a FCFS
basis - How many times ? N-1
24Synchronization Hardware (1)
- Having the support of some simple hardware
instructions, the CS problem can be solved very
easily and efficiently. - The CS problem occurs because the modification of
a shared variable of a process may be
interrupted. - Two common hardware instructions that execute
atomically - Test-and-Set
- Swap
25Synchronization Hardware (2)
- Test and modify the content of a word
atomically. - boolean TestAndSet(boolean target)
- boolean rv target
- target true
- return rv
-
26Mutual Exclusion with Test-and-Set
- Shared data boolean lock false
- Process Pi
- do
- while (TestAndSet(lock))
- critical section
- lock false
- remainder section
-
27Synchronization Hardware
- Atomically swap two variables.
- void Swap(boolean a, boolean b)
- boolean temp a
- a b
- b temp
-
28Mutual Exclusion with Swap
- Shared data (initialized to false) boolean
lock /global variable -
- Process Pi
- do
- key true
- while (key true)
- Swap(lock, key)
- critical section
- lock false
- remainder section
-
29Semaphores
- Synchronization tool that does not require busy
waiting. - Semaphore S integer variable (By Dijkstra)
- can only be accessed via indivisible (atomic)
operations - wait (S) P operation
- while S ? 0 /no-op S--
- signal (S) V operation
- S
atomic
30Critical Section of n Processes
- Shared data
- semaphore mutex / initially mutex 1
- Process Pi
- do wait(mutex)
- critical section
- signal(mutex) remainder section
while (1), - Mutual exclusion Yes
- Progress Yes
- Bounded waiting Yes using a queue
31- A more complicated example
- (Initially, all semaphores a g are 0)
- begin
- parbegin
- begin S1 signal(a) signal(b) end
- begin wait(a) S2 S4 signal(c) signal(d)
end - begin wait(b) S3 signal(e) end
- begin wait(c) S5 signal(f) end
- begin wait(d) wait(e) S6 signal(g) end
- begin wait(f) wait(g) S7 end
- parend
- end
a
b
e
d
c
f
g
32 Semaphore Implementation(1)
- The main disadvantage of mutual-exclusion
solutions is busy waiting (wasting CPU cycles in
the loops of enter section). - A CS had better be as short as possible
- The semaphore defined before also has the same
problem. Thus, the type of semaphore is also call
a spinlock (spin while waiting for the lock). - To overcome the need for busy waiting, we can
modify the definition of P and V, using block and
wakeup operations. And define a semaphore as a
record typedef struct - int value struct process L
semaphore
33Semaphore Implementation (2)
- Semaphore operations now defined as
- wait(S) S.value--
- if (S.value lt 0)
- add this process to S.L block
- signal(S) S.value
- if (S.value lt 0)
- remove a process P from S.L wakeup(P)
-
34Semaphore Implementation (3)
- signal(S) and wait(S) should be atomic. This
situation is a CS problem (no two processes can
executed wait() and signal() on the same
semaphore simultaneously). - Solutions
- uniprocessor system inhibit interrupts during
the execution of signal and wait operations - multiprocessor system, interrupt does not work
here - Note that busy waiting have not be completely
eliminated. - It is removed from the entry to the CSs of
application programs. - It is limited to CSs of signal and wait
operations, which are short.
35Semaphore as a General Synchronization Tool
- Execute B in Pj only after A executed in Pi
- Use semaphore flag initialized to 0
- Code
- Pi Pj
- ? ?
- A wait(flag)
- signal(flag) B
36Deadlocks and Starvation
- The using of semaphores may cause deadlocks
- Starvation indefinite blocking. A process may
never be removed from the semaphore queue in
which it is suspended - For example waiting queues are implemented in
LIFO order.
(Initially, AB1)
P0
P1
wait(B) wait(A) S1 signal(B) signal(A)
wait(A) wait(B) S0 signal(A) signal(B)
deadlock
37Two 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.
38Implementing S as a Binary Semaphore
- Data structures
- binary-semaphore S1, S2
- int C
- Initialization
- S1 1
- S2 0
- C initial value of counting semaphore
S
39Implementing S
- wait operation / S11, S20 and CS initially
- wait(S1)
- C--
- if (C lt 0)
- signal(S1)
- wait(S2)
-
- signal(S1)
- signal operation
- wait(S1)
- C
- if (C lt 0)
- signal(S2)
- else
- signal(S1)
Wait (S)