Synchronization
Semaphores
Classic Problems of Synchronization
Monitors
Synchronization Examples
Alternative Approaches
5.2
Objectives
To present the concept of process synchronization.
To introduce the critical-section problem, whose solutions can
critical-section problem
problems
synchronization problems
5.3
Background
Processes can execute concurrently
inconsistency
Suppose that we wanted to provide a solution to the consumerproducer 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, counteris 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.
5.4
Producer
while (true) {
/* produce an item in next produced */
while (counter == BUFFER_SIZE) ;
/* do nothing */
buffer[in] = next_produced;
in = (in + 1) % BUFFER_SIZE;
counter++;
}
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 */
}
5.6
Race Condition
counter++ could be implemented as
register1 = counter
register1 = register1 + 1
counter = register1
5.7
{register1 = 5}
{register1 = 6}
{register2 = 5}
{register2 = 4}
{counter = 6 }
{counter = 4}
5.8
Critical Section
General structure of process Pi
5.9
5.10
5.11
Critical-Section Handling in OS
Two approaches depending on if kernel is preemptive or nonpreemptive
5.12
Petersons Solution
Good algorithmic description of solving the problem
Two process solution
Assume that the
int turn;
Boolean flag[2]
section
ready!
5.13
5.14
5.15
Synchronization Hardware
Many systems provide hardware support for implementing the
Atomic = non-interruptible
5.16
5.17
test_and_set Instruction
Definition:
boolean test_and_set (boolean *target)
{
boolean rv = *target;
*target = TRUE;
return rv:
}
1. Executed atomically
2. Returns the original value of passed parameter
3. Set the new value of passed parameter to TRUE.
5.18
5.19
compare_and_swap Instruction
Definition:
int compare _and_swap(int *value, int expected, int new_value) {
int temp = *value;
if (*value == expected)
*value = new_value;
return temp;
}
1. Executed atomically
2. Returns the original value of passed parameter value
3. Set the variable value the value of the passed parameter new_value
but only if value ==expected. That is, the swap takes place only under
this condition.
5.20
5.21
5.22
Mutex Locks
Previous solutions are complicated and generally inaccessible
to application programmers
problem
Simplest is
mutex lock
Calls to
5.23
; /* busy wait */
available = false;;
}
release() {
available = true;
}
do {
acquire lock
critical section
release lock
remainder section
} while (true);
5.24
Semaphore
Synchronization tool that provides more sophisticated ways (than Mutex locks) for
process to synchronize their activities.
wait(S) {
while (S <= 0)
; // busy wait
S--;
}
signal(S) {
S++;
}
Operating System Concepts 9th Edition
5.25
Semaphore Usage
5.26
Semaphore Implementation
Must guarantee that no two processes can execute the
wait()
where the wait and signal code are placed in the critical
section
5.27
Two operations:
typedef struct{
int value;
struct process *list;
} semaphore;
5.28
5.29
Let
P1
wait(S);
wait(Q);
wait(Q);
wait(S);
...
...
signal(S);
signal(Q);
signal(Q);
signal(S);
5.30
schemes
Bounded-Buffer Problem
Dining-Philosophers Problem
5.31
Bounded-Buffer Problem
n buffers, each can hold one item
Semaphore
Semaphore
Semaphore
5.32
5.33
5.34
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
Only one single writer can access the shared data at the same time
Shared Data
Data set
5.35
5.36
5.37
write ASAP
reader-writer locks
5.38
Dining-Philosophers Problem
Shared data
5.39
eat
signal (chopstick[i] );
signal (chopstick[ (i + 1) % 5] );
//
think
} while (TRUE);
5.40
5.41
5.42
Monitors
A high-level abstraction that provides a convenient and effective
mechanism for process synchronization
Abstract data type, internal variables only accessible by code within the
procedure
Only one process may be active within the monitor at a time
But not powerful enough to model some synchronization schemes
monitor monitor-name
{
// shared variable declarations
procedure P1 () { . }
procedure Pn () {}
Initialization code () { }
}
}
5.43
5.44
Condition Variables
condition x, y;
Two operations are allowed on a condition variable:
5.45
5.46
Options include
Signal and wait P waits until Q either leaves the monitor or it waits
for another condition
5.47
5.48
5.49
pickup() and
DiningPhilosophers.pickup(i);
EAT
DiningPhilosophers.putdown(i);
No deadlock, but starvation is possible
5.50
= 1)
= 0)
wait(mutex);
body of F;
if (next_count > 0)
signal(next)
else
signal(mutex);
Mutual exclusion within a monitor is ensured
5.51
= 0)
x_count++;
if (next_count > 0)
signal(next);
else
signal(mutex);
wait(x_sem);
x_count--;
5.52
if (x_count > 0) {
next_count++;
signal(x_sem);
wait(next);
next_count--;
}
5.53
5.54
R.acquire(t);
...
access the resurce;
...
R.release;
Where R is an instance of type
ResourceAllocator
5.55
5.56
Synchronization Examples
Solaris
Windows
Linux
Pthreads
5.57
Solaris Synchronization
Implements a variety of locks to support multitasking, multithreading
Uses adaptive mutexes for efficiency when protecting data from short
code segments
If lock held by non-run-state thread, block and sleep waiting for signal of
lock being released
to data
5.58
Windows Synchronization
Uses interrupt masks to protect access to global resources on
uniprocessor systems
Events
5.59
Linux Synchronization
Linux:
Linux provides:
Semaphores
atomic integers
spinlocks
5.60
Pthreads Synchronization
Pthreads API is OS-independent
It provides:
mutex locks
condition variable
read-write locks
spinlocks
5.61
Alternative Approaches
Transactional Memory
OpenMP
Functional Programming Languages
5.62
Transactional Memory
A memory transaction is a sequence of read-write operations
void update()
{
/* read/write memory */
}
5.63
OpenMP
OpenMP is a set of compiler directives and API that support
parallel progamming.
5.64
5.65
End of Chapter 5