Module-3
Module No. 3 Process coordination and Dead Lock 10 Hours
Process synchronization, critical-section problem, Peterson's solution, synchronization hardware,
semaphores, monitors, classic problems of synchronization. System model, deadlock
characterization, methods for handling deadlocks, deadlock prevention, deadlock avoidance,
deadlock detection, recovery from deadlock.
DR. Radha Mohan Pattanayak 1
What is concurrency?
Concurrency is the concept of executing two or more tasks at the same time (in parallel). Tasks
may include methods (functions), parts of a program, or even other programs.
T1 T2 T3 T1 T2 T3 T1 T2 T3 ....
<---------------------------Time-----------------------
Parallelism in Single Core System
Core 1 T1 T3 T1 T3 T1 ....
Core 2 T2 T4 T2 T4 T2 ....
<---------------------------Time-----------------------
Parallelism in Multi Core System
Advantages of Concurrency
Running of multiple applications –
It enable to run multiple applications at the same time.
Better resource utilization –
It enables that the resources that are unused by one application can be used for
other applications.
Better average response time –
Without concurrency, each application has to be run to completion before the
next one can be run.
Major problems using Concurrency
Sharing global resources –
Sharing of global resources safely is difficult. If two processes both make use
of a global variable and both perform read and write on that variable, then the
order in which various read and write are executed is critical.
Optimal allocation of resources –
DR. Radha Mohan Pattanayak 2
It is difficult for the operating system to manage the allocation of resources
optimally.
Concept of Threads
Thread is a light weight process (LWP) comprising of ….
Thread ID
Program Counter
Register set
Stack
Threads created belongs to the same process will share both code, data section, and
files etc.
DR. Radha Mohan Pattanayak 3
In a multi-threading model there are three different threads such as….
Many-to-One
One-to-One
Many-to-Many
Many-to-One Multithreading Models
Many user-level threads mapped to single kernel thread.
One thread blocking, it causes all to block.
Multiple threads may not run in parallel on multi-core system because only one may be
in kernel at a time.
Many-to-Many Multithreading Models
Allows many user level threads to be mapped to many kernel threads.
Allows the operating system to create a sufficient number of kernel threads.
Solaris prior to version 9.
DR. Radha Mohan Pattanayak 4
One-to-One Multithreading Models
Each user-level thread maps to kernel thread.
Creating a user-level thread creates a kernel thread.
More concurrency than many-to-one.
Number of threads per process sometimes restricted due to overhead.
Examples
Windows
Linux
Critical Section Problem:
Consider a system consisting of n processes (P0 , P1 , ………Pn -1 ) each process has a
segment of code which is known as critical section in which the process may be
changing common variable, updating a table, writing a file and so on.
The important feature of the system is that when the process is executing in its critical
section no other process is to be allowed to execute in its critical section.
The execution of critical sections by the processes is a mutually exclusive.
The critical section problem is to design a protocol that the process can use to cooperate
each process must request permission to enter its critical section.
The section of code implementing this request is the entry section. The critical section
is followed on exit section. The remaining code is the remainder section.
DR. Radha Mohan Pattanayak 5
Example:
do
{
Entry Section;
Critical Section;
Exit Section;
Remainder Section;
} while ( true ) ;
Solution to Critical Section Problem
A solution to the critical section problem must satisfy the following three conditions.
1. Mutual Exclusion: If process Pi is executing in its critical section then no any other
process can be executing in their critical section.
2. Progress: Progress means that if one process doesn't need to execute into critical
section then it should not stop other processes to get into the critical section.
If no process is executing in its critical section and some process wish to enter their
critical sections then only those process that are not executing in their remainder section
can enter its critical section next.
3. Bounded waiting: There exists a bound on the number of times that other processes
are allowed to enter their critical sections after a process has made a request.
We should be able to predict the waiting time for every process to get into the critical
section. The process must not be endlessly waiting for getting into the critical section.
Peterson Solution to Critical Section Problem
Peterson’s solution is a software based solution to the critical section problem.
DR. Radha Mohan Pattanayak 6
In this solution, when a process is executing in a critical state, then the other process
only executes the rest of the code, and the opposite can happen. This method also helps
to make sure that only a single process runs in the critical section at a specific time.
Peterson’s solution used two variables such as turn and flag to share the critical section.
The variable indicates whose turn it is to enter the critical section. i.e. if turn = i, then
process Pi is allowed to execute in it’s critical section.
The flag array is used to indicate if a process is ready to enter the critical section.
i.e. if flag [i] = true, then the process Pi is ready to enter into critical section.
Structure of process Pi & Pj in Peterson’s Solution
do{ do {
flag [ i ] = true ; flag [ j ] = true ;
trun = j ; trun = 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);
To prove Mutual exclusion is preserved.
Pi enters its critical section only if either flag[j]==false or turn==i.
If both processes want to enter their critical sections at the same time,
the flag[i] == flag[j] == true.
However, the value of turn can be either 0 or 1 but cannot be both.
Hence, one of the processes must have successfully executed the while statement (to enter its
critical section), and the other process has to wait, till the process leaves its critical section.
To prove Progress is preserved.
Case 1: Pi is ready to enter its critical section.
If Pj is not ready to enter the critical section (it is in the remainder section).
DR. Radha Mohan Pattanayak 7
Then flag[j] == false, and Pi can enter its critical section.
Case 2: Pi and Pj are both ready to enter its critical section.
Let for this flag[i] == flag[j] == true.
And for turn it is either turn == i or turn == j.
If turn == i, then Pi will enter the critical section.
If turn == j, then Pj will enter the critical section.
To prove Bounded waiting is preserved.
Once Pj exits its critical section, it will reset flag[j] to false, allowing Pi to enter its critical
section.
• Even if Pj immediately resets flag[j] to true, it must also set turn to i.
• Then, Pi will enter the critical section after at most one entry by Pj.
Mutex Locks
Mutex is a mutual exclusion object that synchronizes access to a resource.
Mutex ensures that only one thread has access to a critical section or data by using
operations like first acquire() a lock then release() the lock.
A thread having the lock of mutex can use the critical section while other threads must
wait till the lock is released.
Advantages of Mutex Locks:
Mutex is simple operation by putting locks before entering its critical section
and then releasing it.
DR. Radha Mohan Pattanayak 8
Since only one thread is in its critical section at any given time, there are no race
conditions, and data always remain consistent.
Drawbacks of Mutex Locks:
If a thread obtains a lock and goes to sleep or is preempted, then the other thread
may not move forward. This may lead to starvation.
Only one thread should be allowed in the critical section at a time.
The normal implementation may lead to a busy waiting state, which wastes CPU
time.
What is a Semaphore in OS?
Semaphores are integer variables that are used to solve the critical section problem by
using two atomic operations, wait and signal that are used for process synchronization.
Types of Semaphore in OS?
Semaphores are divided into two types such as…
Binary Semaphores
Counting Semaphores
Binary Semaphores :
The value of a binary semaphore ranges between 0and 1.
In binary semaphore, if a process wants to access the resource, it performs the
wait() operation on the semaphore and decrements the value of the semaphore
from 1 to 0. When it releases the resource, it performs a signal() operation on
the semaphore and increments its value to 1.
Suppose the value of the semaphore is 0 and a process wants to access the resource. In that
case, it performs wait() operation and block itself till the current process utilizing the resources
releases the resource.
DR. Radha Mohan Pattanayak 9
Wait: The wait operation decrements the value of its argument S if it is positive. If S is negative
or zero, then no operation is performed.
wait(S)
{
while (S<=0);
S--;
}
Signal: The signal operation increments the value of its argument S.
signal (S)
{
S++;
}
Counting Semaphores :
The semaphore S value is initialized to the number of resources present in the
system.
Whenever a process wants to access the resource, it performs the
wait()operation on the semaphore and decrements the semaphore value by one.
When it releases the resource, it performs the signal() operation on the
semaphore and increments the semaphore value by one.
When the semaphore count goes to 0, it means the processes occupy all
resources.
1
DR. Radha Mohan Pattanayak
0
The classical problems of synchronization are as follows:
Bound-Buffer problem
Sleeping barber problem
Dining Philosophers problem
Readers and writers problem
Bound-Buffer problem of process synchronization
The Bound-Buffer problem is otherwise known as Producer-Consumer problem.
The Producer-Consumer problem is a classical multi-process synchronization problem,
where we are trying to achieve synchronization between more than one processes.
There is one Producer in the producer-consumer problem, Producer is producing some
items, whereas there is one Consumer that is consuming the items produced by the
Producer. The same memory buffer is shared by both producers and consumers which
is of fixed-size.
The task of the Producer is to produce the item, put it into the memory buffer, and again
start producing items. Whereas the task of the Consumer is to consume the item from
the memory buffer.
Conditions for Producer consumer Problem :
The producer should produce data only when the buffer is not full. In case it is
found that the buffer is full, the producer is not allowed to store any data into
the memory buffer.
Data can only be consumed by the consumer if and only if the memory buffer
is not empty. In case it is found that the buffer is empty, the consumer is not
allowed to use any data from the memory buffer.
Accessing memory buffer should not be allowed to producer and consumer at
the same time.
To solve this problem, we need 3 counting semaphores – Full, Empty and Mutex.
Full: It represents the number of items in the buffer at any given time
Empty: It keeps track of number of unoccupied slots in the buffer.
Mutex: This semaphore variable is used to achieve mutual exclusion between
processes.
Before Starting the process the initial semaphore values are....
mutex = 1
Full = 0 // Initially, all slots are empty.
Empty = n // All slots are empty initially
1
DR. Radha Mohan Pattanayak
1
Producer Process Consumer Process
do { do {
... wait(full);
// produce an item wait(mutex);
... ...
wait(empty) ; // remove item from buffer
wait(mutex) ; ...
... signal(mutex);
// add into buffer signal(empty);
... ...
signal(mutex) ; // consume the item
signal(full) ; ...
} while (true) ;
} while (true) ;
Semaphores used in Producer Code:
wait(empty) will decrease the value of the counting semaphore variable empty by 1, that is
when the producer produces some element then the value of the space gets automatically
decreased by one in the buffer. In case the buffer is full, that is the value of the counting
semaphore variable "empty" is 0, then wait(empty); will trap the process (as per definition of
wait) and does not allow to go further.
wait(S) decreases the binary semaphore variable S to 0 so that no other process which is willing
to enter into its critical section is allowed.
signal(s) increases the binary semaphore variable S to 1 so that other processes who are willing
to enter into its critical section can now be allowed.
signal(full) increases the counting semaphore variable full by 1, as on adding the item into the
buffer, one space is occupied in the buffer and the variable full must be updated.
Semaphores used in Consumer Code:
wait(full) will decrease the value of the counting semaphore variable full by 1, that is when
the consumer consumes some element then the value of the full space gets automatically
decreased by one in the buffer. In case the buffer is empty, that is the value of the counting
semaphore variable full is 0, then wait(full); will trap the process(as per definition of wait) and
does not allow to go further.
1
DR. Radha Mohan Pattanayak
2
wait(S) decreases the binary semaphore variable S to 0 so that no other process which is willing
to enter into its critical section is allowed.
signal(S) increases the binary semaphore variable S to 1 so that other processes who are willing
to enter into its critical section can now be allowed.
signal(empty) increases the counting semaphore variable empty by 1, as on removing an item
from the buffer, one space is vacant in the buffer and the variable empty must be updated
accordingly.
Sleeping barber problem of process synchronization
There is a barber shop which has one barber, one barber chair, and n chairs for waiting for
customers if there are any to sit on the chair.
If there is no customer, then the barber sleeps in his own chair.
When a customer arrives, he has to wake up the barber.
If there are many customers and the barber is cutting a customer’s hair, then the
remaining customers either wait if there are empty chairs in the waiting room or they
leave if no chairs are empty.
The solution of this problem is to include three Semaphores.
The first one to count the number of customers present in the waiting room.
The second one for the barber. 0 and 1 are used to signify if the barber is idle or not.
The third mutex is for mutual exclusion. It is needed for the program to run.
The customer keeps a track of the number of customers in the waiting line.
1
DR. Radha Mohan Pattanayak
3
If the number of customers in the waiting line is equal to the number of waiting chairs,
then the upcoming customer leaves the barbershop.
The barber executes the barber procedure, blocking the semaphore customers because
it is initially 0.
Dining Philosopher problem of process synchronization
The dining philosopher's problem represents that Five philosophers are sitting around
a circular table and their job is to think and eat alternatively.
A bowl of noodles is placed at the center of the table along with five chopsticks for
each of the philosophers.
To eat a philosopher needs both their right and a left chopstick. A philosopher can only
eat if both immediate left and right chopsticks of the philosopher is available.
In case if both immediate left and right chopsticks of the philosopher are not available
then the philosopher puts down their (either left or right) chopstick and starts thinking
again.
Initially, each element of the semaphore C0, C1, C2, C3, and C4 are initialized to 1 as the
chopsticks are on the table and not picked up by any of the philosophers.
1
DR. Radha Mohan Pattanayak
4
void Philosopher
{
while(1)
{
Wait( take_chopstickC[i] );
Wait( take_chopstickC[(i+1) % 5] ) ;
...
EATING THE NOODLE
...
Signal( put_chopstickC[i] );
Signal( put_chopstickC[ (i+1) % 5] ) ;
.
. THINKING
}
}
Drawback of Dining Philosopher problem
If all the philosophers pick their left chopstick at the same time, which leads to the
condition of deadlock and none of the philosophers can eat.
Solutions to Dining Philosopher problem
Maximum number of philosophers on the table should not be more than four, in this
case, chopstick C4 will be available for philosopher P3, so P3 will start eating and after
the finish of his eating procedure, he will put down his both the chopstick C3 and C4,
i.e. semaphore C3 and C4 will now be incremented to 1. Now philosopher P2 which
was holding chopstick C2 will also have chopstick C3 available, hence similarly, he
will put down his chopstick after eating and enable other philosophers to eat.
A philosopher at an even position should pick the right chopstick and then the left
chopstick while a philosopher at an odd position should pick the left chopstick and then
the right chopstick.
Only in case if both the chopsticks ( left and right ) are available at the same time, only
then a philosopher should be allowed to pick their chopsticks
Readers and writers problem
The readers-writers problem is a classical problem of process synchronization, it relates
to a data set such as a file that is shared between more than one process at a time.
1
DR. Radha Mohan Pattanayak
5
If two or more than two readers want to access the file at the same point in time there
will be no problem.
However, in other situations like when two writers or one reader and one writer wants
to access the file at the same point of time, there may occur some problems.
However, multiple readers can access the object at the same time.
The solution of readers and writers can be implemented using two binary semaphores
as "write" and "mutex“.
Explanation for readers code:
Initial value of semaphore mutex = 1 and variable readcount = 0
Wait( mutex ); //now mutex = 0
readcount = readcount + 1 ;
if (readcount == 1)
{
wait (write); // decrement write by 1, i.e. write = 0
}
signal(mutex); // now mutex = 1 i.e. other readers are allowed to enter.
readcount - - ;
if (readcount == 0)
{
Signal (write); // i.e. write = 1, and writer can enter
Signal ( mutex ); // Reader leaves
}
Explanation for writers code:
Wait( write ); // now write = 0 implies no other writer can access the file
WRITE INTO THE FILE
signal ( write );
If a writer wishes to access the file, wait operation is performed on write semaphore,
which decrements write to 0 and no other writer can access the file. On completion of
1
DR. Radha Mohan Pattanayak
6
the writing job by the writer who was accessing the file, the signal operation is
performed on write.
1
DR. Radha Mohan Pattanayak
7