Anda di halaman 1dari 9

Operating Systems Implementation Introduction 2

COMP3300 Process synchronization helps maintain data consistency when


cooperating processes share data.
Synchronization is important for both user applications and the
Synchronization operating system's implementation.

Department of Computer Science


The Australian National University

Eric McCreath

2004

Count Example 3 Count Example 4

Suppose we have a shared variable count. And count keeps Implementing the increment operation in machine language
track of the number of threads currently servicing a request for a could require three instructions:
daemon. LOAD count -> R1
ADD R1 1 -> R1
Thread Pi. STORE R1 -> count
do Similarly for the decrement operation:
count := count +1 LOAD count -> R1
service request ADD R1 -1 -> R1
count := count -1 STORE R1 -> count
od
This will not always work!
Count Example 5 Critical-Section Problem 6

Suppose count = 3 and a new thread starts to service a request We first look at a software solution where we assume process
as an old one completes. The resulting value in count could be have shared memory.
2, 3, or 4 even though there is still only 3 threads servicing a Consider n processes {P1,P 2, .... , Pn} where each process has a
request.
critical-section. The critical section is a portion of the text which
This occurs because we allow the variable count to be modified modifies/reads shared data. Only one process is permitted to
concurrently. The outcome depends on the order the operations execute in the critical section at a time.
are executed. This is known as a race condition. The solution is
to guard count so only one process may use it at a time. To this text we add two items an entry section and an exit
section of code. The entry section guards entry to the critical
section and the exit section is used to indicate the process has
exited the critical section.
(We will cover much of this material very quickly as I am
assuming people have a background in it from COMP2310.)

Critical-Section Problem 7 Critical-Section Problem 8

A typical process Pi. A solution to the critical section problem must satisfy the
following conditions:
Mutual Exclusion - No process may enter a critical section
loop do while another process is already executing in the critical section.
remainder section Progress - The selection of a process to enter the critical may
entry code not be postponed indefinitely. Also this selection may not be
dependent on processes executing in the remainder sections.
critical section
Bounded Waiting - If process A requests entry into the critical
exit section section then there exists a bound on the number of times other
remainder section processes enter the critical section before process A.

od
Critical-Section Problem 9 Critical-Section Problem 10

What is the problem with the following solution? Lets try using a shared array of booleans for the flag.
initialize
initialize flag[0] := false
turn := 0 flag[1] := false
Process P0 Process P1
loop do Process P0 Process P1
loop do
remainder section remainder section loop do loop do
while turn <> 0 do no-op while turn <> 1 do no-op remainder section remainder section
critical section critical section flag[0] := true flag[1] := true
turn := 1 turn := 0 while flag[1] do no-op while flag[0] do no-op
remainder section remainder section critical section critical section
od od flag[0] := false flag[1] := false
remainder section remainder section
od od

Critical-Section Problem 11 Critical-Section Problem 12

By combining the key ideas of the previous two approaches we


obtain a correct solution. One solution to the multiple-process critical-section problem is
initialize the bakery algorithm.
flag[0] := false The bakery algorithm uses a ticket system where processes
flag[1] := false wishing to enter the critical section receive a numbered ticket.
turn := 0
The process with the lowest ticket enters the critical section.
Process P0 Process P1
This solution uses the follow shared data items:
loop do loop do
remainder section remainder section booleanchoosing[n];
flag[0] := true flag[1] := true intticket[n];
turn :=1 turn :=0 A total ordering is also defined over ticket number/process id.
while flag[1] && turn == 1 do while flag[0] && turn == 0 do
no-op no-op
critical section critical section
flag[0] := false flag[1] := false




t 1, p1 t 2, p 2 t1 t 2 t 1 t 2 p1 p 2






remainder section remainder section
od od
Critical-Section Problem 13 Critical-Section Problem 14

The following solution embraces the main idea behind the initialize
bakery algorithm, however, it fails on the mutual exclusion for (i=0;i<n;i++)
condition. ticket[i] := 0
choosing[i] := false
initialize Process Pi of the bakery algorithm
for (i=0;i<n;i++) loop do
ticket[i] := 0 remainder section
Process Pi choosing[i] := true
loop do ticket[i] := max(ticket[0],ticket[1],..,ticket[n-1]) + 1
remainder section choosing[i] := false
ticket[i] := max(ticket[0],ticket[1],..,ticket[n-1]) + 1 for (j=0; j<n; j++) {
for (j=0; j<n; j++) while choosing[j] do no-op
while ticket[j] <> 0 && ((ticket[j],j) < (ticket[i],i)) do no-op while ticket[j] <> 0 && ((ticket[j],j) < (ticket[i],i)) do no-op
critical section }
ticket[i] := 0 critical section
remainder section ticket[i] := 0
od remainder section
od

Synchronization Hardware 15 Synchronization Hardware 16

Hardware support is introduced to make synchronization easier. There are some problems with this approach, these include:
One approach is to turn off interrupts. This would stop a context increases response time,
switch during a critical section. OS looses control,
Process Pi critical sections must be quick, and
loop do the approach will not work on a multiprocessor system.
remainder section
turn interrupts off
critical section
turn interrupts on
remainder section
od
Synchronization Hardware 17 Test-and-Set 18

Two atomic instructions that help support synchronization are: boolean test-and-set(var target:boolean)
if target then
Test-and-Set, and return true
else
Swap.
target := true
Atomic instructions are uninterruptible. return false
fi
When they are executed simultaneously the result will be
identical to a sequential execution in some arbitrary order. lock is shared variable which is initialized to false.
Process Pi
loop do
remainder section
while test-and-set(lock) do no-op
critical section
lock := false
remainder section
od

Swap 19 Hardware Solution 20

void swap(var a, b : boolean) The following solution satisfies all the critical-section problem
t := a conditions. This solution uses the following shared variables:
a := b
b := t boolean lock
Given lock is a shared variable which is initialized to false. boolean waiting[n]
Process Pi A process will enter the critical section in one of two possible
loop do ways:
remainder section These solutions do not
it obtains the 'lock' first, or
key := true satisfy the bounded waiting
while key do swap(key,lock) condition. a process exiting the critical section allows it to start.
critical section
lock := false
remainder section
od
Hardware Solution 21 Semaphores 22

Process Pi
Semaphores are synchronization tools. They provided a high-
loop do level mechanism for both addressing the critical section
remainder section problem and coordination between processes.
waiting[i] := true
key := true It may be thought of as a 'class' consisting of an integer S which
while waiting[i] && key do swap(key,lock) is accessed through two procedures:
waiting[i] := false
critical section wait(S) - Wait until semaphore S is greater than zero. When S
j := i + 1 mod n is greater than zero decrement S and continue.
while j <> i && !waiting[i] do j := j+1 mod n signal(S) - Increment semaphore S.
if j = i then
lock := false
else
waiting[j] := false
fi
remainder section
od

Semaphores 23 Semaphores 24

wait(S : semaphore) Suppose n processes share a semaphore mutex then the critical
section problem may be solved as follows:
while S <= 0 do no-op
mutex is initialized to 1.
S := S -1
signal(S : semaphore)
Process Pi
S := S + 1 loop do
remainder section
wait(mutex)
The testing/modification of the semaphore value must be critical section
executed indivisibly. The above routines are intended to show signal(mutex)
functionality not implementation details. remainder section
od
Semaphores 25 Semaphores 26

Semaphores may also be used to coordinate processes. All the solutions given so far require busy waiting. This is an
inefficient use of the CPU resource.
Suppose some portion of code T1 in process P1 must be
executed after process P0 completes executing T0. This may be addressed by placing a waiting process on a queue
and blocking that process. The queue will be attached to the
synch is initialized to 0.
semaphore in question and a signal will wake up processes from
Process P0 Process P1 this queue. Although, the implementation is different to that of
: : the busy waiting approach the functionality is the same.
T0 wait(synch)
signal(synch) T1
: :

Semaphores 27 Semaphores 28

wait(S : semaphore)
A set of processes {P1,...,Pn } may all be waiting on a set of
S := S -1 semaphores. If the only processes that 'signal' these semaphores
if S < 0 then are a subset of {P1,...,Pn }then clearly none of these processes
add this process to a list waiting on S will proceed. This condition is known as a deadlock.
block Care must be taken when programming with semaphores.
if In many respects the synchronization provided by semaphores
Both the wait and signal is limited as their use spreads out over a monolithic block of
signal(S : semaphore) implementations must be
'atomic'. code. Rather than bring the synchronization into the confines
S := S + 1 section of code that provides an OO type of approach.
if S <= then
remove a process from the waiting list
wakeup this process
fi
Semaphores 29 Semaphores 30

Although the following section of code may function perfectly Starvation occurs when processes waits indefinitely within the
most of the time, there is a chance of them being deadlocked. semaphore. This may occur if a LIFO queue is used by the
Given two semaphores S and Q which are initialized to 1. semaphore's implementation.
A binary semaphore is simply a semaphore(or counting
semaphore) which value may take on either 0 or 1.
Process P0 Process P1
A counting semaphore may be implemented with a binary
wait(Q) semaphore.
wait(S)
wait(Q) wait(S)
: :
: :
signal(Q) signal(S)
signal(S) signal(Q)

Bounded-Buffer Problem 31 Bounded-Buffer Problem 32

Often cooperating processes act as producer/consumer pairs. Given n is the size of the buffer. Three semaphores are used:
Shared memory may be used as a buffer where the: mutex, empty, and full. These semaphores are initialized to 1, n,
and 0 respectively.
producer writes to the buffer, and
the consumer reads from the buffer.
This is known as the bounded- buffer problem. Semaphores Process Pproducer Process Pconsumer
may be used to correctly coordinate both the producer and the loop do loop do
consumer. produce item x wait(full)
wait(empty) wait(mutex)
wait(mutex) obtain x from the buffer
add x to the buffer signal(mutex)
signal(mutex) signal(empty)
signal(full) consume item x
od od
Readers and Writers Problem 33 Readers and Writers Problem 34

The Readers and Writers Problem involves synchronizing mutex and wrt are semaphores which are initialized to 1.
processes which either read or write to a shared data structure. readcount is an integer which is initialized to 0.
There may be many readers reading the data at once. However, Process Pwriter Process Preader
there may be only one writer and this writer may not write while loop do loop do
other processes are reading this shared data. : :
wait(wrt) wait(mutex)
One of two approaches are taken when solving this problem write to shared document readcount := readcount + 1
either: signal(wrt) if readcount == 1 then wait(wrt)
If there are readers reading the data and a writer wishes to write : signal(mutex)
to the data then no new readers are permitted to start reading od read from to shared document
until the writer has finished. wait(mutex)
readcount := readcount - 1
If the document is currently being read by a reader then any if readcount == 0 then signal(wrt)
new reader may start reading the data. (This may starve the signal(mutex)
writer from writing to the document.) :
od

Higher level synchronization 35

Some languages also provide synchronization :


monitors,
OO languages (eg java syn primitives), and
message passing.

Anda mungkin juga menyukai