Unit 3 Os
Unit 3 Os
Chapter 3
PROBLEMS WITH CONCURRENT
EXECUTION
Concurrent processes (or threads) often need to share
data (maintained either in shared memory or files) and
resources
If there is no controlled access to shared data, some
processes will obtain an inconsistent view of this data
The action performed by concurrent processes will then
depend on the order in which their execution is
interleaved
AN EXAMPLE
waitB(S):
if (S.value = 1) {
S.value := 0;
} else {
block this process
place this process in S.queue
}
signalB(S):
if (S.queue is empty) {
S.value := 1;
} else {
remove a process P from S.queue
place this process P on ready list
}
PROBLEMS WITH SEMAPHORES
semaphores provide a powerful tool for enforcing mutual
exclusion and coordinate processes
But wait(S) and signal(S) are scattered among several
processes. Hence, difficult to understand their effects
Usage must be correct in all the processes
One bad (or malicious) process can fail the entire
collection of processes
USING SEMAPHORES FOR SOLVING
CRITICAL SECTION PROBLEMS
For n processes
Initialize S.count to 1 Process Pi:
repeat
Then only 1 process is allowed into wait(S);
CS (mutual exclusion) CS
To allow k processes into CS, we signal(S);
initialize S.count to k RS
forever
MUTEX LOCKS
acquire() {
while (!available)
; /* busy wait */
available = false;
}
release() {
available = true;
}
do {
acquire lock
critical section
release lock
remainder section
} while (true);
MONITORS
Are high-level language constructs that provide equivalent
functionality to that of semaphores but are easier to control
n buffers,
each can hold one item
Semaphore mutex initialized to the value 1
Semaphore full initialized to the value 0
Semaphore empty initialized to the value n
BOUNDED BUFFER PROBLEM (CONT.)
do {
...
/* produce an item in next_produced */
...
wait(empty);
wait(mutex);
...
/* add next produced to the buffer */
...
signal(mutex);
signal(full);
} while (true);
BOUNDED BUFFER PROBLEM (CONT.)
Do {
wait(full);
wait(mutex);
...
/* remove an item from buffer to next_consumed */
...
signal(mutex);
signal(empty);
...
/* consume the item in next consumed */
...
} while (true);
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
⚫ Semaphore mutex initialized to 1
⚫ Integer read_count initialized to 0
READERS-WRITERS PROBLEM (CONT.)
do {
wait(rw_mutex);
...
/* writing is performed */
...
signal(rw_mutex);
} while (true);
READERS-WRITERS PROBLEM (CONT.)
The structure of a reader process
do {
wait(mutex);
read_count++;
if (read_count == 1)
wait(rw_mutex);
signal(mutex);
...
/* reading is performed */
...
wait(mutex);
read count--;
if (read_count == 0)
signal(rw_mutex);
signal(mutex);
} while (true);
READERS-WRITERS PROBLEM
VARIATIONS
Each philosopher is a
process Process Pi:
One semaphore per fork: repeat
think;
⚫ fork: array[0..4] of wait(fork[i]);
semaphores wait(fork[i+1 mod 5]);
⚫ Initialization: eat;
fork[i].count:=1 for i:=0..4 signal(fork[i+1 mod 5]);
signal(fork[i]);
A first attempt: forever
Deadlock if each
philosopher start by picking
his left fork!
THE DINING PHILOSOPHERS
PROBLEM
A solution: admit only 4 Process Pi:
philosophers at a time that repeat
think;
tries to eat wait(T);
Then 1 philosopher can wait(fork[i]);
always eat when the other 3 wait(fork[i+1 mod 5]);
are holding 1 fork eat;
signal(fork[i+1 mod 5]);
Hence, we can use another signal(fork[i]);
semaphore T that would signal(T);
limit at 4 the number of forever
philosophers “sitting at the
table”
Initialize: T.count:=4