Process Synchronization Operating System Concepts Background The Critical-Section Problem

advertisement
Process Synchronization
Operating System Concepts
•
•
•
•
•
•
•
•
Module 4: PROCESS SYNCHRONIZATION
Andrzej Bednarski, Ph.D. student
Department of Computer and Information Science
Linköping University, Sweden
E-mail: andbe@ida.liu.se
Background
The Critical-Section Problem
Synchronization Hardware
Semaphores
Classical Problems of Synchronization
Critical Regions
Monitors
Atomic Transactions
URL: http://www.ida.liu.se/~andbe
The lecture notes are mainly based on Silberschatz’s, Galvin’s and Gagne’s book (“Operating System Concepts”, 6th ed.,
Addison-Wesley, 2002). No part of the lecture notes may be reproduced in any form, due to the copyrights reserved by
Addison-Wesley. These lecture notes should only be used for internal teaching purposes at the Linköping University.
4.1
TDDB63 – Operating System Concepts –
Background
•
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 (Chapter 4)
allows at most n – 1 items in buffer at the same time. A solution,
where all N buffers are used is not simple.
+ 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
•
Race Condition: outcome of execution depends on a particular
order
A. Bednarski
•
4.3
Bounded-Buffer (Cont.)
•
•
4.2
Additional shared variable:
+ int counter = 0;
Producer process:
while (1) {
/* produce an item in nextProduced */
while (counter == BUFFER_SIZE)
; /* do nothing */
buffer[in] = nextProduced;
in = (in + 1) % BUFFER_SIZE;
counter++;
}
TDDB63 – Operating System Concepts –
•
•
4.4
•
•
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 (protocol).
Structure of process Pi
do {
entry section
critical section
exit section
reminder section
} while (1);
The statements:
+ counter = counter + 1;
+ counter = counter - 1;
must be executed atomically.
A. Bednarski
A. Bednarski
The Critical Section Problem
Consumer process:
while (1) {
while (counter == 0)
; /* do nothing */
nextConsumed = buffer[out];
out = (out + 1) % BUFFER_SIZE;
counter--;
}
TDDB63 – Operating System Concepts –
A. Bednarski
Bounded-Buffer
•
TDDB63 – Operating System Concepts –
TDDB63 – Operating System Concepts –
4.5
TDDB63 – Operating System Concepts –
A. Bednarski
4.6
1
Initial Attempts to Solve Problem
Solution 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.
•
•
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);
2. Progress. If no process is executing in its critical section and
there exist 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.
3. 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.
O Assume that each process executes at a nonzero speed
O No assumption concerning relative speed of the n processes.
TDDB63 – Operating System Concepts –
A. Bednarski
4.7
Algorithm 1
•
•
•
•
•
Satisfies mutual exclusion, but not progress
+ If turn==0 and P1 ready to enter critical section, P1
cannot do so even though P0 is in its remainder section
+ Not sufficient information about the state of each process
A. Bednarski
•
4.9
4.8
Shared variables:
boolean flag[2] = {false, false};
+ flag [i] == true Ÿ Pi ready to enter its critical section
Process Pi
do {
flag[i] = true;
while (flag[j]);
critical section
flag[i] = false;
remainder section
} while (1);
Satisfies mutual exclusion, but not progress
requirement.
+ P0 sets flag[0]=true; P1 sets flag[1]=true
=> infinite loop
TDDB63 – Operating System Concepts –
A. Bednarski
4.10
Bakery Algorithm
Combined shared variables of algorithms 1 and 2.
Process Pi
do {
flag[i] = true;
turn = j;
while (flag[j] && turn == j );
critical section
flag[i] = false;
remainder section
} while (1);
Meets all three requirements; solves the critical-section
problem for two processes.
TDDB63 – Operating System Concepts –
A. Bednarski
Algorithm 2
Algorithm 3
•
Processes may share some common variables to synchronize their
actions.
TDDB63 – Operating System Concepts –
Shared variables:
int turn = 0;
+ turn == i Ÿ Pi can enter its critical section
Process Pi
do {
while (turn != i);
critical section
turn = j
remainder section
} while(1);
TDDB63 – Operating System Concepts –
•
•
•
A. Bednarski
Critical section for n processes
4.11
•
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 < 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...
TDDB63 – Operating System Concepts –
A. Bednarski
4.12
2
Bakery Algorithm (Cont.)
Structure of Pi
Bakery Algorithm (Cont.)
•
Notation <{
{ lexicographical 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 t ai for i = 0,
…, n – 1
•
Shared data:
boolean choosing[n];
int number[n];
do {
choosing[i] = true;
number[i] = max(number[0], number[1], …, number [n – 1])+1;
choosing[i] = false;
for (j = 0; j < n; j++) {
while (choosing[j]); /* busy waiting */
while ( (number[j] != 0) &&
(number[j],j) < (number[i], i) );
}
critical section
number[i] = 0;
remainder section
} while (1);
Data structures are initialized to false and 0 respectively
TDDB63 – Operating System Concepts –
A. Bednarski
4.13
TDDB63 – Operating System Concepts –
4.14
A. Bednarski
Synchronization Hardware
Mutual Exclusion with TestAndSet
•
•
Shared data:
boolean lock = false ;
•
Process Pi
do {
while (TestAndSet(lock)); /* busy wait */
•
•
Idea: avoid/disable interrupts while common variables are
changed
Not applicable in multi-processor environments
Test and modify the content of a word atomically: uninterruptable
unit.
boolean TestAndSet(boolean &target) {
boolean rv = target;
target = true ;
return rv;
}
If multiple TestAndSet instructions are executed simultaneously
(each on a different CPU), then they are executed sequentially in
some arbitrary order.
TDDB63 – Operating System Concepts –
A. Bednarski
4.15
TestAndSet: Pros and Cons
- Busy waiting is employed (spinning)
- Starvation is possible: when a process leaves a critical section and
more than one process is waiting, the selection of a waiting
process is arbitrary; thus, some process could indefinitely be
denied access.
- Deadlock is possible:
(i) P1 executes and enters its critical section
(ii) P2 interrupts P1 due to high pri., but cannot enter its critical
section
(iii) P1 never dispatches again, since it’s low priority job
A. Bednarski
lock = false;
/* release lock */
remainder section
} while (1);
TDDB63 – Operating System Concepts –
4.16
A. Bednarski
Semaphores
+ Applicable to any number of processes on either uni- or multiprocessor machine
+ Simple and therefore easy to verify
+ Can support multiple critical sections (each critical section can be
defined by its own variable)
TDDB63 – Operating System Concepts –
critical section
4.17
•
•
•
•
Synchronization tool that does not require busy waiting.
Synchronization operations are atomic, i.e. indivisible
+ Operation P = wait (Dutch for proberen (test))
+ Operation V = signal (Dutch for verhogen (increment))
Applicability:
+ N-process critical section problems
+ Synchronization problems, e.g., precedence constraints
Semaphore S – integer variable
wait (S ) {
while (S <= 0)
; /* no-op */
S – –;
}
TDDB63 – Operating System Concepts –
A. Bednarski
signal (S ) {
S ++;
}
4.18
3
Example: Critical Section of n Processes
Pros and Cons
•
Shared variable:
semaphore mutex = 1;
•
Cons:
+ “Spin-lock” method -> requires busy waiting
•
Process Pi
•
Pros:
+ Spin-lock has no context switching when waiting;
+ Applicable in Multi-processor environments
•
Solution to busy-waiting: block yourself!
do {
wait(mutex);
critical section
signal(mutex);
reminder section
} while (1);
TDDB63 – Operating System Concepts –
A. Bednarski
4.19
Semaphore Implementation
•
Define a semaphore as a struct
typedef struct {
int value;
struct process *L;
} semaphore;
•
Assume two simple operations:
+ block suspends the process that invokes it.
+ wakeup(P ) resumes the execution of a blocked process P.
TDDB63 – Operating System Concepts –
A. Bednarski
Execute B in Pj only after A executed in Pi
•
Use semaphore flag initialized to 0
•
Code:
Pi
A
signal(flag)
TDDB63 – Operating System Concepts –
•
4.21
4.20
Semaphore operations now defined as:
void wait(semaphore S) {
S.value--;
if (S.value < 0) {
add this process to S.L;
block();
}
}
void signal(semaphore S) {
S.value++;
if (S.value <= 0) {
remove a process P from S.L;
wakeup(P );
}
}
TDDB63 – Operating System Concepts –
A. Bednarski
4.22
Deadlock and Starvation
•
Deadlock – two or more processes are waiting indefinitely for an
event that can be caused by only one of the waiting processes.
•
Let S and Q be two semaphores initialized to 1
P0
P1
wait(S );
wait(Q );
wait(Q );
wait(S );
signal(S );
signal(Q );
signal(Q )
signal(S);
•
Starvation – indefinite blocking. A process may never be
removed from the semaphore queue in which it is suspended.
(e.g., LIFO order)
Pj
wait(flag)
B
A. Bednarski
A. Bednarski
Implementation (Cont.)
Semaphore as a General
Synchronization Tool
•
TDDB63 – Operating System Concepts –
4.23
TDDB63 – Operating System Concepts –
A. Bednarski
4.24
4
Implementing S using Binary
Semaphore
Two 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 with a binary
semaphore.
•
TDDB63 – Operating System Concepts –
A. Bednarski
binary-semaphore S1, S2;
int C;
•
wait operation
signal operation
TDDB63 – Operating System Concepts –
Initialization:
S1 = 1;
S2 = 0;
C = initial value of semaphore S
4.25
Implementing S (Cont.)
•
Data structures:
TDDB63 – Operating System Concepts –
A. Bednarski
Classical Problems of Synchronization
wait(S1);
C--;
if (C < 0) {
signal (S1);
wait (S2);
}
signal (S1);
•
Bounded-Buffer Problem
•
Readers and Writers Problem
•
Dining-Philosophers Problem
wait (S1);
C++;
if (C <= 0)
signal (S2);
else
signal (S1);
A. Bednarski
4.27
TDDB63 – Operating System Concepts –
A. Bednarski
Bounded-Buffer Problem
Bounded-Buffer Problem (Cont.)
•
Producer process
Consumer process
do {
…
produce an item in nextp
wait (empty);
wait (mutex);
…
add nextp to buffer
…
signal (mutex);
signal (full);
} while(1);
do {
wait (full)
wait (mutex);
…
remove an item from buffer to
nextc
…
signal (mutex);
signal (empty);
…
consume the item in nextc
…
} while (1);
Shared data
typedef struct {
…
} item;
item buffer[BUFFER_SIZE];
semaphore full = n, empty = 0, mutex = 1;
…
TDDB63 – Operating System Concepts –
4.26
A. Bednarski
4.29
TDDB63 – Operating System Concepts –
A. Bednarski
4.28
4.30
5
Readers-Writers Problem
•
Readers-Writers Problem (Cont.)
•
Shared data
semaphore mutex = 1, wrt = 1;
int readcount = 0;
•
Writer process
wait (wrt);
…
writing is performed
…
signal (wrt);
TDDB63 – Operating System Concepts –
A. Bednarski
4.32
Dining-Philosophers Problem
TDDB63 – Operating System Concepts –
A. Bednarski
Philosopher i :
- Guarantees that neighbors are not eating simultaneously!
- Does not guarantee avoidance of deadlocks!
4.34
TDDB63 – Operating System Concepts –
A. Bednarski
Dining-Philosophers Problem
Three Deadlock-Free Solutions
Programming problems using
semaphores
•
Allow at most four philosophers to be sitting simultaneously at the
table
•
Allow a philosopher to pick up her/his chopsticks only if both
chopsticks are available (both in the same critical section)
signal(mutex)
critical section
wait(mutex)
Results in what?
wait(mutex)
critical section
wait(mutex)
Results in what?
•
4.33
do {
wait(chopstick[i ]);
wait(chopstick[(i+1) % 5]);
…
eat
…
signal(chopstick[i]);
signal(chopstick[(i+1) % 5]);
…
think
…
} while (1);
Shared data
semaphore chopstick[5] = {1, 1, 1, 1, 1};
TDDB63 – Operating System Concepts –
A. Bednarski
Dining-Philosophers Problem (Cont.)
•
•
Reader process
wait(mutex);
readcount++;
if (readcount == 1)
wait(wrt);
signal(mutex);
…
reading is performed
…
wait(mutex);
readcount --;
if (readcount == 0)
signal(wrt);
signal(mutex):
Odd philosophers pick up left chopstick first; even philosophers
pick up right chopstick first
(Asymmetric solution)
4.35
Ommittance of signal or wait, what happens?
TDDB63 – Operating System Concepts –
A. Bednarski
4.36
TDDB63 – Operating System Concepts –
A. Bednarski
4.37
6
Critical Regions
Critical Regions (Cont.)
•
High-level synchronization construct
+ Can use, e.g., semaphores at low level.
•
Regions referring to the same shared variable exclude each other
in time.
•
A shared variable v of type T, is declared as:
v: shared T;
•
•
Variable v accessed only inside region statements
region v when B do S;
When a process tries to execute the region statement, the
boolean expression B is evaluated. If B is true, statement S is
executed. If it is false, the process is delayed until B becomes
true and no other process is in the region associated with v.
•
Pros:
+ Protects against certain simple errors associated with
semaphore solution, that may be made by the programmer.
where B is a boolean expression.
While statement S is being executed, no other process can access
variable v.
TDDB63 – Operating System Concepts –
A. Bednarski
4.38
TDDB63 – Operating System Concepts –
A. Bednarski
Example – Bounded Buffer
Bounded Buffer Example (Cont.)
•
•
•
Shared variables:
struct buffer {
item pool[n];
int count, in, out;
};
Producer process inserts nextp into the shared buffer
region buffer when (count < n) {
pool[in] = nextp;
in = in+1 % n;
count++;
}
TDDB63 – Operating System Concepts –
A. Bednarski
Consumer process removes an item from the shared buffer and
puts it in nextc.
region buffer when (count > 0) {
nextc =pool[out];
out = (out+1) % n;
count--;
}
4.40
TDDB63 – Operating System Concepts –
A. Bednarski
Monitors
Monitors cont.
•
•
To allow a process to wait within the monitor, a condition
variable must be declared, as
condition x, y;
•
Condition variable can only be used with the operations wait
and signal.
+ The operation
x.wait();
means that the process invoking this operation is
suspended until another process invokes
x.signal();
+ The x.signal operation resumes exactly one suspended
process. If no process is suspended, then the signal
operation has no effect
(Note, in comparison, when using traditional semaphores,
the value of the semaphore is changed)
High-level synchronization construct that allows the safe sharing
of an abstract data type among concurrent processes.
monitor monitor-name {
shared variable declarations
procedure body P1 (…) {
…}
procedure body P2 (…) {
…}
procedure body Pn (…) {
…}
{
initialization code
}
}
TDDB63 – Operating System Concepts –
A. Bednarski
4.39
4.45
TDDB63 – Operating System Concepts –
A. Bednarski
4.41
4.46
7
Schematic Overview of a Monitor
TDDB63 – Operating System Concepts –
A. Bednarski
Monitor with condition variables
4.47
Dining Philosophers Example
TDDB63 – Operating System Concepts –
…
void test(int i) {
if ((state[(i+4) % 5] != eating) &&
(state[i] == hungry) &&
(state[(i+1) % 5] != eating)) {
state[i] = eating;
self[i].signal ();
}
}
void pickup(int i) {
state[i] = hungry;
test (i);
if (state[i] != eating) self[i].wait();
void putdown (int i) {
state[i] = thinking;
test((i+4) % 5);
test((i+1) % 5);
}
A. Bednarski
void init() {
for (int i = 0; i < 5; i++)
state[i] = thinking;
}
}
4.49
TDDB63 – Operating System Concepts –
A. Bednarski
Atomic Transactions
Concurrent Atomic Transactions
•
Transactions - several operations grouped as one logical
atomic/indivisible step of execution
+ Commit or abort (roll back)
•
•
•
•
•
Database technique
Could provide more flexible and powerful techniques at OS level
”Transaction Processing Systems”
•
•
Log-based Recovery
Checkpoints
+ Log-recovery is performed since the last checkpoint (i.e., not
the entire log)
TDDB63 – Operating System Concepts –
A. Bednarski
4.48
Dining Philosophers cont.
monitor dp {
enum { thinking, hungry, eating } state[5];
condition self[5];
TDDB63 – Operating System Concepts –
A. Bednarski
4.56
4.50
Serializability
Locking protocol - ensures serializability
+ 2PL - Two phase locking
Growing phase: a transaction only obtains locks
Shrinking phase: a transaction only releases locks
TDDB63 – Operating System Concepts –
A. Bednarski
4.57
8
Summary
Recommended Reading and Exercises
•
•
•
•
•
Reading:
+ All but take 7.8 light
•
Exercises:
+ 1-16, 18-20, (21)
Cooperation processes
Mutual exclusion (critical section)
Semaphores / Condition / Critical region / Monitor
Transaction
TDDB63 – Operating System Concepts –
A. Bednarski
4.58
TDDB63 – Operating System Concepts –
A. Bednarski
4.59
9
Download