Classical Problems of Synchronization
Classical Problems of Synchronization
where a finite buffer pool is used to exchange messages between producer and
consumer processes.
● Because the buffer pool has a maximum size, this problem is often called the
semaphores "full" and "empty" to keep track of the current number of full and
● There are five philosophers sitting around a table, in which there are five
chopsticks/forks kept beside them and a bowl of rice in the centre, When a
philosopher wants to eat, he uses two chopsticks - one from their left and one
from their right. When a philosopher wants to think, he keeps down both
shared data, and never change it, and there are other processes(called writers)
who may change the data in addition to reading, or instead of reading it.
the classic problems of synchronization. Let's start by understanding the problem here,
are two processes running, namely, producer and consumer, which are operating on
the buffer.
A producer tries to insert data into an empty slot of the buffer. A consumer tries to
remove data from a filled slot in the buffer. As you might have guessed by now, those
two processes won't produce the expected output if they are being executed
concurrently.
There needs to be a way to make the producer and consumer work in an independent
manner.
Here's a Solution
One solution of this problem is to use semaphores. The semaphores which will be used
here are:
● empty, a counting semaphore whose initial value is the number of slots in the
At any instant, the current value of empty represents the number of empty slots in the
buffer and full represents the number of occupied slots in the buffer.
do
wait(empty);
// acquire lock
wait(mutex);
signal(mutex);
// increment 'full'
signal(full);
while(TRUE)
● Looking at the above code for a producer, we can see that a producer first waits
● Then it decrements the empty semaphore because, there will now be one less
empty slot, since the producer is going to insert data in one of those slots.
● Then, it acquires lock on the buffer, so that the consumer cannot access the
● After performing the insert operation, the lock is released and the value of full is
incremented because the producer has just filled a slot in the buffer.
do
wait(mutex);
signal(mutex);
// increment 'empty'
signal(empty);
while(TRUE);
● The consumer waits until there is atleast one full slot in the buffer.
● Then it decrements the full semaphore because the number of occupied slots will
● Following that, the consumer completes the removal operation so that the data
multiple processes.
table has five chopsticks and a bowl of rice in the middle as shown in the below figure.
eat, he uses two chopsticks - one from their left and one from their right. When a
philosopher wants to think, he keeps down both chopsticks at their original place.
amount of time. But when a philosopher starts eating, he has to stop at some point of
while(TRUE)
wait(stick[i]);
/*
*/
wait(stick[(i+1) % 5]);
/* eat */
signal(stick[i]);
signal(stick[(i+1) % 5]);
/* think */
When a philosopher wants to eat the rice, he will wait for the chopstick at his left and
picks up that chopstick. Then he waits for the right chopstick to be available, and then
But if all five philosophers are hungry simultaneously, and each of them pickup one
chopstick, then a deadlock situation occurs because they will be waiting for another
● A philosopher must be allowed to pick up the chopsticks only if both the left and
● Allow only four philosophers to sit at the table. That way, if all the four
philosophers pick up four chopsticks, there will be one chopstick left on the table.
So, one philosopher can start eating and eventually, two chopsticks will be
two types of processes in this context. They are reader and writer. Any number of
readers can read from the shared resource simultaneously, but only one writer can
write to the shared resource. When a writer is writing data to the resource, no other
process can access the resource. A writer cannot write to the resource if there are non
The Solution
From the above problem statement, it is evident that readers have higher priority than
writer. If a writer wants to write to the resource, it must wait until there are no readers
used to maintain the number of readers currently accessing the resource. The variable
Instead of having the process to acquire lock on the shared resource, we use the mutex
m to make the process to acquire and release lock whenever it is updating the
read_count variable.
wait(w);
signal(w);
And, the code for the reader process looks like this:
while(TRUE)
//acquire lock
wait(m);
read_count++;
if(read_count == 1)
wait(w);
//release lock
signal(m);
/* perform the reading operation */
// acquire lock
wait(m);
read_count--;
if(read_count == 0)
signal(w);
// release lock
signal(m);
● After performing the write operation, it increments w so that the next writer can
● On the other hand, in the code for the reader, the lock is acquired whenever the
● When a reader wants to access the resource, first it increments the read_count
value, then accesses the resource and then decrements the read_count value.
● The semaphore w is used by the first reader which enters the critical section and
● The reason for this is, when the first readers enters the critical section, the writer
is blocked from the resource. Only new readers can access the resource now.
● Similarly, when the last reader exits the critical section, it signals the writer using
the w semaphore because there are zero readers now and a writer can have the
Problem : The analogy is based upon a hypothetical barber shop with one barber. There
is a barber shop which has one barber, one barber chair, and n chairs for waiting for
● 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
customer which counts the number of customers present in the waiting room
(customer in the barber chair is not included because he is not waiting). Second, the
barber 0 or 1 is used to tell whether the barber is idle or is working, And the third mutex
is used to provide the mutual exclusion which is required for the process to execute. In
the solution, the customer has the record of the number of customers waiting in the
waiting room if the number of customers is equal to the number of chairs in the waiting
When the barber shows up in the morning, he executes the procedure barber, causing
him to block on the semaphore customers because it is initially 0. Then the barber goes
When a customer arrives, he executes customer procedure the customer acquires the
mutex for entering the critical region, if another customer enters thereafter, the second
one will not be able to anything until the first one has released the mutex. The customer
then checks the chairs in the waiting room if waiting customers are less then the
number of chairs then he sits otherwise he leaves and releases the mutex.
If the chair is available then customer sits in the waiting room and increments the
variable waiting value and also increases the customer’s semaphore this wakes up the
barber if he is sleeping.
At this point, customer and barber are both awake and the barber is ready to give that
person a haircut. When the haircut is over, the customer exits the procedure and if there
Semaphore Customers = 0;
Semaphore Barber = 0;
Mutex Seats = 1;
int FreeSeats = N;
Barber {
while(true) {
down(Customers);
seats.*/
down(Seats);
FreeSeats++;
up(Barber);
up(Seats);
Customer {
while(true) {
if(FreeSeats > 0) {
/* sitting down.*/
FreeSeats--;
up(Customers);
up(Seats);
/* wait in the waiting room if barber is
busy. */
down(Barber);
} else {
up(Seats);
// customer leaves