5. Synch

advertisement
Operating Systems
Certificate Program in Software Development
CSE-TC and CSIM, AIT
September -- November, 2003
5. Process Synchronization
(Ch. 6, S&G)
ch 7 in the 6th ed.
 Objectives
– describe the synchronization problem and
some common mechanisms for solving it
OSes: 5. Synch
1
Contents
1. Motivation: Bounded Buffer
2. Critical Sections
3. Synchronization Hardware
4. Semaphores
5. Synchronization Examples
OSes: 5. Synch
continued
2
6.
Problems with Semaphores
7.
Critical Regions
8.
Monitors
9.
Synchronization in Solaris 2
10. Atomic Transactions
OSes: 5. Synch
3
1. Motivation: Bounded Buffer
bounded buffer
…..
0
producer
OSes: 5. Synch
1 2 3
write
…..
n-1
read
consumer
4
Producer Code (pseudo-Pascal)
:
repeat
. . .
/* produce an itemP */
. . .
while (counter == n) do
no-op;
buffer[in] := itemP;
in := (in+1) mod n;
counter := counter + 1;
until false;
:
OSes: 5. Synch
/* write */
5
Consumer Code
:
repeat
while (counter == 0) do
no-op;
itemC := buffer[out];
/* read */
out := (out+1) mod n;
counter := counter - 1;
. . .
/* use itemC for something */
. . .
until false;
:
OSes: 5. Synch
6
Problem
 Assume counter == 5
 producer run
:
counter :=
counter + 1;
:

counter
OSes: 5. Synch
consumer run
:
counter :=
counter - 1;
:
may now be 4, 5, or 6. Why?
7
Machine Language

“counter := counter + 1”
reg1 := counter
reg1 := reg1 + 1
counter := reg1
becomes:
 “counter := counter - 1”
reg2 := counter
reg2 := reg2 - 1
counter := reg2
OSes: 5. Synch
becomes:
8
Execution Interleaving
 The
concurrent execution of the two
processes is achieved by interleaving the
execution of each
 There
are many possible interleavings,
which can lead to different values for
counter
– a different interleaving may occur each time
the processes are run
OSes: 5. Synch
9
Interleaving Example
 Initially: counter == 5
 Execution:
reg1 :=
reg1 :=
reg2 :=
reg2 :=
counter
counter
OSes: 5. Synch
counter
reg1 + 1
counter
reg2 - 1
:= reg1
:= reg2
//
//
//
//
//
//
reg1 ==
reg1 ==
reg2 ==
reg2 ==
counter
counter
5
6
5
4
== 6
== 4
10
Summary of Problem
 Incorrect
results occur because of a race
condition over the modification of the
shared variable (counter)
 The
processes must be synchronized while
they are sharing data so that the result is
predictable and correct
OSes: 5. Synch
11
2. Critical Sections
 A critical
section is a segment of code
which can only be executed by one process
at a time
– all other processes are excluded
– called mutual exclusion
OSes: 5. Synch
12
Critical Section Pseudo-code
repeat
entry section
critical section
exit section
remainder section
until false;
OSes: 5. Synch
13
Implementation Features
 An
implementation of the critical section
idea must have three features:
– mutual exclusion
– progress
 the
next process to enter the critical region is
decided solely by looking at those waiting in their
entry sections
– bounded waiting
 no
OSes: 5. Synch
process should wait forever in their entry section
14
2.1. Solutions for Two Processes
 Algorithm
1 (take turns)
– shared data:
var turn: 0..1 := 0;
/* or 1 */
– Code for process i:
repeat
while (turn /== i) do no-op:
critical section;
turn := j;
progress requirement
remainder section;
not met
until false;
OSes: 5. Synch
15
Algorithm2
(who wants to enter?)
 Shared data:
var flag : array [0..1] of boolean
:= {false, false};
 Code for process i:
repeat
flag[i] := true;
while (flag[j]) do no-op:
critical section;
flag[i] := false;
remainder section;
progress requirement
until false;
still not met
OSes: 5. Synch
16
Algorithm 3
 Combines
(Peterson, 1981)
algorithms 1 and 2
– who wants to enter?
– if both do then take turns
 Shared data:
var flag : array [0..1] of boolean
:= {false, false};
var turn : 0..1 := 0;
OSes: 5. Synch
/* or 1 */
continued
17
 Code for process i:
repeat
flag[i] := true;
turn := j;
while (flag[j] and turn == j) do
no-op:
critical section;
flag[i] := false;
remainder section;
until false;
OSes: 5. Synch
18
2.2. Multiple Processes
 Uses
the bakery algorithm (Lamport 1974).
 Each
customer (process) receives a number
on entering the store (the entry section).
 The
customer with the lowest number is
served first (enters the critical region).
OSes: 5. Synch
continued
19
 If
two customers have the same number,
then the one with the lowest name is served
first
– names are unique and ordered
OSes: 5. Synch
20
Pseudo-code
 Shared data:
var choosing : array [0..n-1]
of boolean
:= {false .. false};
var number : array [0..n-1]
of integer
:= {0 .. 0};
OSes: 5. Synch
continued
21
 Code
for process i:
repeat
choosing[i] := true;
number[i] := max(number[0], number[1],
. . ., number[n-1]) + 1;
choosing[i] := false;
for j := 0 to n-1 do
begin
while (choosing[j]) do no-op;
while ((number[j] /== 0) and
((number[j],j) < (number[i],i))) do no-op;
end;
critical section
number[i] := 0;
remainder section
until false;
OSes: 5. Synch
22
3. Synchronization Hardware
 Hardware
solutions can make software
synchronization much simpler
 On
a uniprocessor, the OS can disallow
interrupts while a shared variable is being
changed
– not so easy on multiprocessors
OSes: 5. Synch
continued
23
 Typical
hardware support:
– atomic test-and-set of a boolean (byte)
– atomic swap of booleans (bytes)
 Atomic
means an uninterruptable ‘unit’ of
work.
OSes: 5. Synch
24
3.1. Atomic Test-and-Set
function Test-and-Set(
var target : boolean) : boolean
begin
Test-and-Set := target;
target := true;
end;
OSes: 5. Synch
25
Use
lock/in lock/out result action
F
T
F
proceed
T
T
T
loop
 Shared data:
var lock : boolean := false;
 Process code for mutual exclusion:
repeat
while (Test-and-Set(lock) do
no-op;
critical section
lock := false;
remainder section
until false;
OSes: 5. Synch
26
3.2. Atomic Swap
procedure Swap(var a, b : boolean)
var temp : boolean;
begin
temp := a;
a := b;
b := temp;
end;
OSes: 5. Synch
27
Use
key1
in: T
key2
T
…
…
keyN lock
T
F
 Shared data:
var lock : boolean := false;
 Process code for m.e.:
var key : boolean:
repeat
key := true;
repeat
Swap(lock, key);
until (key == false);
critical section
lock := false;
remainder section
until false;
OSes: 5. Synch
28
3.3. Bounded Waiting
 TestAndSet()
and Swap() both satisfy the
requirements of mutual exclusion and
progress
 But
bounded waiting is not satisfied
 We
must add an extra data structure to code
FIFO (queueing-style) behaviour
OSes: 5. Synch
29
4. Semaphores
(Dijkstra, 1965)
 Semaphores
are a synchronization tool
based around two atomic operations:
OSes: 5. Synch
– wait()
sometimes called P()
– signal()
sometimes called V()
30
4.1. Definitions
same as integer
procedure wait(var S : semaphore)
begin
while (S =< 0) do
no-op;
S := S - 1;
end;
procedure signal(var S : semaphore)
begin
S := S + 1;
end;
OSes: 5. Synch
31
4.2. Mutual Exclusion with Semaphores
 Shared data:
var mutex : semaphore := 1;
 Process code:
repeat
wait(mutex);
critical section;
signal(mutex);
remainder section;
until false;
OSes: 5. Synch
32
4.3. Ordering Processes
 Establish
a fixed order for two processes
p1 and p2 , We set semaphore Order := 0.
 If
the desired order is p1 -> p2, p2 should
issue a wait(Order), and then wait until p1
issues a signal(Order).
OSes: 5. Synch
33
4.4. Counting Semaphores
 Allow
N processes into a critical section,
by initialising semaphore Limit to N
– the first N processes each decrement Limit
using wait(Limit), until Limit == 0, at
which time new processes must wait
 This
approach is used for controlling
access to a limited number of resources
(e.g. N resources)
OSes: 5. Synch
34
4.5. Implementations
 Our wait()
implementation uses busy-waiting
– sometimes called a spinlock
 An
alternative is for the process calling wait()
to block
– place itself on a wait list associated with the
semaphore
– signal() chooses a blocked process to become
ready
OSes: 5. Synch
35
New Semaphore Data Type
type semaphore =
record
value : integer;
L : list of waiting-processes;
end;
OSes: 5. Synch
36
New Operations
procedure wait(var S : semaphore)
begin
S.value := S.value - 1;
if (S.value < 0) then
begin
/* add the calling process to S.L */
. . .
block;
end;
end;
OSes: 5. Synch
continued
37
procedure signal(var S : semaphore)
begin
S.value := S.value + 1;
if (S.value =< 0) then
begin
/* remove a process P from S.L */
. . .
wakeup(P);
end;
end;
OSes: 5. Synch
38
4.6. Deadlocks & Starvation
 Deadlock
occurs when every process is
waiting for a signal(S) call that can only be
carried out by one of the waiting processes.
 Starvation
occurs when a waiting process
never gets selected to move into the critical
region.
OSes: 5. Synch
39
4.7. Binary Semaphores
 A binary
semaphore is a specialisation of
the counting semaphore with S only having
a range of 0..1
– S starts at 0
– easy to implement
– can be used to code up counting semaphores
OSes: 5. Synch
40
5. Synchronization Examples
OSes: 5. Synch
 5.1.
Bounded Buffer
 5.2.
Readers and Writers
 5.3.
Dining Philosophers
41
5.1. Bounded Buffer (Again)
bounded buffer
…..
0
producer
OSes: 5. Synch
1 2 3
write
…..
n-1
read
consumer
42
Implementation
 Shared data:
var buffer : array[0..n-1] of Item;
var mutex : semaphore := 1;
/* for access to buffer */
var full : semaphore := 0;
/* num. of used array cells */
var empty : semaphore := n;
/* num. of empty array cells */
OSes: 5. Synch
43
Producer Code
repeat
. . .
/* produce an itemP */
. . .
wait(empty);
wait(mutex);
buffer[in] := itemP;
in := (in+1) mod n;
signal(mutex);
signal(full);
until false;
OSes: 5. Synch
44
Consumer Code
repeat
wait(full);
wait(mutex);
itemC := buffer[out];
out := (out+1) mod n;
signal(mutex);
signal(empty);
. . .
/* use itemC for something */
. . .
until false;
OSes: 5. Synch
45
5.2. Readers & Writers
 Readers
make no change to the shared data
(e.g. a file)
– no synchronization problem
 Writers
do change the shared data
 Multiple
writers (or a writer and readers)
cause a synchronization problem.
OSes: 5. Synch
46
Many Variations
 1.
Don’t keep a reader waiting unless a
writer is already using the shared data
– writers may starve
 2.
Don’t keep a writer waiting
– readers may starve
OSes: 5. Synch
47
Variation 1
 Shared data:
var shared-data : Item;
var readcount : integer : = 0;
/* no. of readers currently
using shared-data */
var mutex : semaphore := 1;
/* control access to readcount */
var wrt : semaphore := 1;
/* used for m.e. of writers */
OSes: 5. Synch
48
Writer’s Code
:
wait(wrt);
. . .
/* writing is performed */
. . .
signal(wrt);
:
OSes: 5. Synch
49
Reader’s Code
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);
OSes: 5. Synch
50
5.3. Dining Philosophers
Dijkstra, 1965

OSes: 5. Synch
An example of the
need to allocate several
resources (chopsticks)
among processes
(philosophers) in a
deadlock and
starvation free manner.
51
Implementation
 Represent
each chopstick by a semaphore.
Shared data:
var chopstick : array[0..4]
of semaphore
:= {1,1,1,1,1};
 A chopstick
is ‘picked up’ with:
wait(chopstick[pos])
and ‘set down’ with:
signal(chopstick[pos])
OSes: 5. Synch
52
Code for Philopospher i
repeat
wait( chopstick[i] );
wait( chopstick[(i+1) mod 5] );
/* . . . eat . . . */
signal( chopstick[i] );
signal( chopstick[(i+1) mod 5] );
/* . . . think . . . */
until false;
OSes: 5. Synch
53
Deadlock
 This
solution avoids simultaneous use of
chopsticks (good)
 But
if all the philosophers pick up their left
chopstick together, then they will deadlock
while waiting for access to their right
chopstick.
OSes: 5. Synch
54
Possible Fixes
 Allow
at most 4 philosophers to be at the table
at a time.
 Have
a philosopher pick up their chopsticks
only if both are available (in a critical section)
 Alternate
the order that chopsticks are picked
up depending on whether the philosopher is
seated at an odd or even seat
OSes: 5. Synch
55
6. Problems with Semaphores
 The
reversal of a wait() and signal() pair
will break mutual exclusion
 The
omission of either a wait() or signal()
will potentially cause deadlock
 These
problems are difficult to debug and
reproduce
OSes: 5. Synch
56
Higher level Synchronization
 These
problems have motivated the
introduction of higher level constructs:
– critical regions
– monitors
– condition variables
 These
constructs are safer, and easy to
understand
OSes: 5. Synch
57
7. Critical Regions
 Shared variables are explicitly
var v : shared ItemType;
Hoare, 1972;
Brinch Hansen, 1972
declared:
 A shared
variable can only be accessed within
the code part (S) of a region statement:
region v do S
– while code S is being executed, no other process
can access v
OSes: 5. Synch
58
Conditional Critical Regions

region v when B do S
– only execute S when the boolean expression B
evaluates to true, otherwise wait until B is true
– as before, while code S is being executed, no
other process can access v
OSes: 5. Synch
59
Bounded Buffer Again
 Shared
data:
var buffer : shared record
pool : array[0..n-1] of Item;
count, in, out : integer;
end;
OSes: 5. Synch
60
Producer Code
region buffer when (count < n) do
begin
pool[in] := itemP;
in := (in+1) mod n;
count := count + 1;
end;
OSes: 5. Synch
61
Consumer Code
region buffer when (count > 0) do
begin
itemC := pool[out];
out := (out+1) mod n;
count := count - 1;
end;
OSes: 5. Synch
62
8. Monitors
queues associated
var
with condition
variables
Brinch Hansen, 1973
shared data
entry queue of
waiting processes
operations
Fig. 6.20, p.184
OSes: 5. Synch
initialization
code
63
Monitor Syntax
type monitor-name = monitor
variable declarations
procedure entry p1(. . .)
begin . . . end;
:
begin
initialization code
end.
OSes: 5. Synch
64
Features
 When
an instance of a monitor is created, its
initialization code is executed
 A procedure
can access its own variables
and those in the monitor’s variable
declarations
 A monitor
only allows one process to use its
operations at a time
OSes: 5. Synch
65
An OO View of Monitors
 A monitor
is similar to a class
 An
instance of a monitor is similar to an
object, with all private data
 Plus
synchronization: invoking any
operation (method) results in mutual
exclusion over the entire object
OSes: 5. Synch
66
8.1. Condition Variables
 Notation:
var x : condition;
x.wait;
suspend
calling process
x.signal;
resumes
one of the suspended
processes waiting on x
OSes: 5. Synch
67
Condition Variables in Monitors
 What
happens when signal is issued?
 The
unblocked process will be placed on the
ready queue and resume from the statement
following the wait.
 This
would violate mutual exclusion if both
the signaller and signalled process are
executing in the monitor at once.
OSes: 5. Synch
68
Three Possible Solutions
 1.
Have the signaller leave the monitor
immediately after calling signal
 2.
Have the signalled process wait until the
signaller has left the monitor
 3.
Have the signaller wait until the
signalled process has left the monitor
OSes: 5. Synch
69
8.2. Dining Philosophers (Again)
 Useful
data structures:
var state : array[0..4] of
(thinking, hungry, eating);
var self : array[0..4] of condition;
/* used to delay philosophers */
 The
approach is to only set state[i] to
eating if its two neigbours are not eating
– i.e.
and
OSes: 5. Synch
state[(i+4) mod 5]
state[(i+1) mod 5]
=
=
eating
eating
70
Using the dining-philosophers Monitor
 Shared data:
var dp : dining-philosopher;
 Code
in philosopher i:
dp.pickup(i):
/* . . . eat . . . */
dp.putdown(i);
OSes: 5. Synch
71
Monitor implementation
type dining-philosophers = monitor
var state : array[0..4] of
(thinking, hungry, eating);
var self : array[0..4] of condition;
procedure entry pickup(i : 0..4)
begin
state[i] := hungry;
test(i);
if (state[i] /== eating) then
self[i].wait;
end;
OSes: 5. Synch
continued
72
procedure entry putdown(i : 0..4)
begin
state[i] := thinking;
test((i+4) mod 5);
test((i+1) mod 5);
end;
OSes: 5. Synch
continued
73
procedure test(k : 0..4)
begin
if ((state[(k+4) mod 5] /== eating)
and (state[k] == hungry)
and (state[(k+1) mod 5]
/== eating)) then
begin
state[k] := eating;
self[k].signal;
end;
end;
OSes: 5. Synch
continued
74
begin
/* initialization of monitor instance */
for i := 0 to 4 do
state[i] := thinking;
end.
OSes: 5. Synch
75
8.3. Problems with Monitors
 Even
 For
high level operations can be misused.
correctness, we must check:
– that all user processes always call the monitor
operations in the right order;
– that no user process bypasses the monitor and
uses a shared resource directly
– called the access-control problem
OSes: 5. Synch
76
9. Synchronization in Solaris 2
 Uses
a mix of techniques:
– semaphores using spinlocks
– thread blocking
– condition variables (without monitors)
– specialised reader-writer locks on data
OSes: 5. Synch
77
10. Atomic Transactions
 We
want to do all the operations of a critical
section as a single logical ‘unit’ of work
– it is either done completely or not at all
 A transaction
can be viewed as a sequence
of reads and writes on shared data, ending
with a commit or abort operation
 An abort
causes a partial transaction to be
rolled back
OSes: 5. Synch
78
10.1. Log-based Recovery
 Atomicity
is ensured by logging transaction
operations to stable storage
– these can be replayed or used for rollback if
failure occurs
 Log
details:
– transaction name, data name, old value,
new value
OSes: 5. Synch
continued
79
 Write-ahead
logging:
– log a write operation before doing it
– log the transaction start and its commit
OSes: 5. Synch
80
Example
begin transaction
read X
if (X >= a) then
{
read Y
X = X - a
Y = Y + a
write X
write Y
}
end transaction
OSes: 5. Synch
(VUW CS 305)
<Ti, start>
<Ti, X, oldV, newV>
<Ti, Y, oldV, newV>
<Ti, commit>
81
Recovery
 Operations:
– undo( Transactioni )
– redo( Transactioni )
 Possible
states of Transactioni
– committed, but were new values written?
– aborted, but were old values restored?
– unfinished
OSes: 5. Synch
82
10.2. Checkpoints
 A checkpoint
fixes state changes by writing
them to stable storage so that the log file
can be reset or shortened.
OSes: 5. Synch
83
10.3. Concurrent Atomic Transactions
 We
want to ensure that the outcome of
concurrent transactions are the same as if
they were executed in some serial order
– serializability
OSes: 5. Synch
84
A Serial Schedule
 Transaction
0
Fig. 6.23, p.195
Transaction 1
read A
write A
read B
write B
read A
write A
read B
write B
OSes: 5. Synch
85
Conflicting Operations
 Two
operations in different transactions
conflict if they access the same data and one
of them is a write.
 Serializability
must avoid conflicting
operations:
– it can do that by delaying/speeding up when
operations in a transaction are performed
OSes: 5. Synch
86
A Concurrent Serializable Schedule
Fig. 6.24, p.196
 Transaction
0
Transaction 1
read A
write A
read A
write A
read B
write B
read B
write B
OSes: 5. Synch
87
10.4. Locks
 Serializability
can be achieved by locking
data items
 There
are a range of locking modes:
– a shared lock allows multiple reads by
different transactions
– an exclusive lock allows only one transaction
to do reads/writes
OSes: 5. Synch
88
10.5. Timestamping
 One
way of ordering transactions
 Using
the system clock is not sufficient
when transactions may originate on
different machines
OSes: 5. Synch
89
Download