Professional Documents
Culture Documents
نسخة ch5
نسخة ch5
نسخة ch5
Synchronization
Adapted from textbook slides of Operating System Concepts (9th Edition) 5.2
Objectives
Adapted from textbook slides of Operating System Concepts (9th Edition) 5.3
Background
Processes can execute concurrently
May be interrupted at any time, partially completing
execution
Concurrent access to shared data may result in data
inconsistency
Maintaining data consistency requires mechanisms to ensure
the orderly execution of cooperating processes
Illustration of the problem:
Suppose that we wanted to provide a solution to the
consumer-producer problem that fills all* the buffers. We can
do so by having an integer counter that keeps track of the
number of full buffers. Initially, counter is set to 0. It is
incremented by the producer after it produces a new buffer
and is decremented by the consumer after it consumes a
buffer.
while (true) {
/* produce an item in next produced */
Adapted from textbook slides of Operating System Concepts (9th Edition) 5.5
Consumer
while (true) {
while (counter == 0)
; /* do nothing */
next_consumed = buffer[out];
out = (out + 1) % BUFFER_SIZE;
counter--;
/* consume the item in next consumed */
}
Adapted from textbook slides of Operating System Concepts (9th Edition) 5.6
Race Condition
register2 = counter
register2 = register2 - 1
counter = register2
Adapted from textbook slides of Operating System Concepts (9th Edition) 5.8
Critical Section
Adapted from textbook slides of Operating System Concepts (9th Edition) 5.9
Solution to Critical-Section Problem
Any solution to the critical-section problem must satisfy the following
three requirements:
1. Mutual Exclusion - If process Pi is executing in its critical section, then
no other processes can be executing in their critical sections
2. Progress - If no process is executing in its critical section and there
exist some processes that wish to enter their critical section, then only
those processes that are not executing in their remainder sections can
participate in deciding which will enter its critical section next, and 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 critical sections after a process
has made a request to enter its critical section and before that request is
granted
Assume that each process executes at a nonzero speed
No assumption concerning relative speed of the n processes
Adapted from textbook slides of Operating System Concepts (9th Edition) 5.10
Critical-Section Handling in OS
Two approaches depending on if kernel is preemptive or non-
preemptive
Preemptive – allows preemption of process when running
in kernel mode
Non-preemptive – runs until exits kernel mode, blocks, or
voluntarily yields CPU
!Essentially free of race conditions in kernel mode
Adapted from textbook slides of Operating System Concepts (9th Edition) 5.11
Algorithm1 for Solving Critical Section Problem
do {
while (turn == j); // busy waiting.note the semicolon!
critical section
turn = j;
remainder section
} while (true);
Process i Process j
do { do {
while (turn == j); while (turn == i);
critical section critical section
turn = j; turn = i;
Adapted from textbook slides of Operating System Concepts (9th Edition) 5.13
Algorithm of Peterson’s Solution
do {
flag[i] = true;
turn = j;
while (flag[j] && turn = = j);
critical section
flag[i] = false;
remainder section
} while (true);
Process i Process j
do { do {
flag[i] = true; flag[j] = true;
turn = j; turn = i;
while (flag[j] && turn = = j); while (flag[i] && turn = = i);
critical section critical section
flag[i] = false; flag[j] = false;
remainder section remainder section
} while (true); } while (true);
Adapted from textbook slides of Operating System Concepts (9th Edition) 5.14
Peterson’s Solution (Cont.)
Provable that the three Critical Section (CS) requirements are met:
1. Mutual exclusion is preserved
Pi enters CS only if:
either flag[j] = false or turn = i
2. Progress requirement is satisfied
3. Bounded-waiting requirement is met
Adapted from textbook slides of Operating System Concepts (9th Edition) 5.15
Synchronization Hardware
Many systems provide hardware support for implementing the critical section
code.
All solutions below based on idea of locking
Protecting critical regions via locks
Uniprocessors – could disable interrupts while modifying shared variable.
Currently running code would execute without preemption
Generally too inefficient on multiprocessor systems
! Operating systems using this not broadly scalable
Modern machines provide special atomic hardware instructions
! Atomic = non-interruptible
Either test memory word and set value
Or swap contents of two memory words
Adapted from textbook slides of Operating System Concepts (9th Edition) 5.16
Solution to Critical-section Problem Using Locks
do {
acquire lock
critical section
release lock
remainder section
} while (TRUE);
Adapted from textbook slides of Operating System Concepts (9th Edition) 5.17
Mutex Locks
n Previous solutions are complicated and generally inaccessible to application
programmers
n OS designers build software tools to solve critical section problem
n Simplest is mutex lock
n Protect a critical section by first acquire() a lock then release() the
lock
l Boolean variable indicating if lock is available or not
Adapted from textbook slides of Operating System Concepts (9th Edition) 5.18
acquire() and release()
acquire() {
while (!available)
; /* busy wait */
available = false;
}
release() {
available = true;
}
do {
acquire lock
critical section
release lock
remainder section
} while (true);
Adapted from textbook slides of Operating System Concepts (9th Edition) 5.19
Semaphore
Synchronization tool that provides more sophisticated ways (than Mutex locks)
for processes to synchronize their activities.
Semaphore S – integer variable
Can only be accessed via two indivisible (atomic) operations
wait() and signal()
! Originally called P() and V()
Adapted from textbook slides of Operating System Concepts (9th Edition) 5.20
Semaphore Usage
Counting semaphore – integer value can range over an unrestricted
domain.
To control access to finite number of resources.
Semaphore S is initialized to number of resources
To use a resource, perform wait(). When count is zero, all resources are
in use and process has to wait
To release a resource, perform signal()
Binary semaphore – integer value can range only between 0 and 1
Same as a mutex lock
Can solve various synchronization problems
Consider P1 and P2 that require S1 to happen before S2
Create a semaphore “synch” initialized to 0
P1: P2:
S1; wait(synch);
signal(synch); S2;
Adapted from textbook slides of Operating System Concepts (9th Edition) 5.21
Atomicity in Semaphores
Adapted from textbook slides of Operating System Concepts (9th Edition) 5.22
Semaphore Implementation with no Busy waiting
typedef struct{
int value;
struct process *list;
} semaphore;
Adapted from textbook slides of Operating System Concepts (9th Edition) 5.23
Implementation with no Busy waiting (Cont.)
wait(semaphore *S) {
S->value--;
if (S->value < 0) {
add this process to S->list;
block();
• semaphore values may be negative here.
}
• In original definition with busy waiting,
} the values are never negative.
• If a semaphore value is negative, its
magnitude is the number of processes
signal(semaphore *S) { waiting on that semaphore
S->value++;
if (S->value <= 0) {
remove a process P from S->list;
wakeup(P);
}
}
Adapted from textbook slides of Operating System Concepts (9th Edition) 5.24
Deadlock and Starvation
Deadlock – two or more processes are waiting indefinitely for an
event that can be caused only by 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);
Adapted from textbook slides of Operating System Concepts (9th Edition) 5.25
Classical Problems of Synchronization
Adapted from textbook slides of Operating System Concepts (9th Edition) 5.26
Readers-Writers Problem
A data set is shared among a number of concurrent processes
Readers – only read the data set; they do not perform any updates
Writers – can both read and write
Problem – allow multiple readers to read at the same time
Only one single writer can access the shared data at the same time
Several variations of how readers and writers are considered – all involve
some form of priorities
Shared Data
Data set
Semaphore rw_mutex initialized to 1
! mutual exclusion semaphore for the writers.
Semaphore mutex initialized to 1.
! ensures mutual exclusion when the read count is updated
Integer read_count initialized to 0
! keeps track of how many processes are currently reading the object
Adapted from textbook slides of Operating System Concepts (9th Edition) 5.27
Readers-Writers Problem (Cont.)
do {
wait(rw_mutex); //lock out readers and other writers
...
/* writing is performed */
...
signal(rw_mutex); //unlock
} while (true);
Adapted from textbook slides of Operating System Concepts (9th Edition) 5.28
Readers-Writers Problem (Cont.)
The structure of a reader process
do {
wait(mutex); //lock readcount
read_count++; //one more reader
if (read_count == 1) //first reader
wait(rw_mutex); //wait if a writer is in CS
signal(mutex); //unlock readcount
...
/* reading is performed */
...
wait(mutex); //lock readcount
read_count--; //one less reader
if (read_count == 0) //last reader
signal(rw_mutex); //allow any waiting writer
Adapted from textbook slides of Operating System Concepts (9th Edition) 5.30
Synchronization Examples
Solaris
Windows
Linux
Pthreads
Adapted from textbook slides of Operating System Concepts (9th Edition) 5.31
Solaris Synchronization
Implements a variety of locks to support multitasking, multithreading
(including real-time threads), and multiprocessing
Uses spin locks for efficiency when protecting data from short code
segments
Uses condition variables and readers-writers locks when longer
sections of code need access to data
Adapted from textbook slides of Operating System Concepts (9th Edition) 5.32
Windows Synchronization
Adapted from textbook slides of Operating System Concepts (9th Edition) 5.33
Linux Synchronization
Linux:
Prior to kernel Version 2.6, disables interrupts to implement short
critical sections
Version 2.6 and later, fully preemptive
Linux provides:
Semaphores
atomic integers
spinlocks
On single-cpu system, spinlocks replaced by enabling and disabling
kernel preemption
Adapted from textbook slides of Operating System Concepts (9th Edition) 5.34
Pthreads Synchronization
Adapted from textbook slides of Operating System Concepts (9th Edition) 5.35