Classical IPC Problems
Classical IPC Problems
The problem was designed to illustrate the problem of avoiding deadlock, a system state in which no
progress is possible.
One idea is to instruct each philosopher to behave as follows:
• think until the left fork is available; when it is, pick it up
• think until the right fork is available; when it is, pick it up
• eat
• put the left fork down
• put the right fork down
• repeat from the start
This solution is incorrect: it allows the system to reach deadlock. Suppose that all five philosophers
take their left forks simultaneously. None will be able to take their right forks, and there will be a
The solution presented below is deadlock-free and allows the maximum parallelism for an arbitrary
number of philosophers. It uses an array, state, to keep track of whether a philosopher is eating,
thinking, or hungry (trying to acquire forks). A philosopher may move into eating state only if neither
neighbor is eating. Philosopher i's neighbors are defined by the macros LEFT and RIGHT. In other
words, if i is 2, LEFT is 1 and RIGHT is 3.
Solution:
#define N 5 /* number of philosophers */
#define LEFT (i+N-1)%N /* number of i's left neighbor */
#define RIGHT (i+1)%N /* number of i's right neighbor */
#define THINKING 0 /* philosopher is thinking */
#define HUNGRY 1 /* philosopher is trying to get forks */
#define EATING 2 /* philosopher is eating */
typedef int semaphore; /* semaphores are a special kind of int */
int state[N]; /* array to keep track of everyone's state */
semaphore mutex = 1; /* mutual exclusion for critical regions */
semaphore s[N]; /* one semaphore per philosopher */
void philosopher(int i) /* i: philosopher number, from 0 to N1 */
{
while (TRUE){ /* repeat forever */
think(); /* philosopher is thinking */
take_forks(i); /* acquire two forks or block */
eat(); /* yum-yum, spaghetti */
put_forks(i); /* put both forks back on table */
}
}
void take_forks(int i) /* i: philosopher number, from 0 to N1 */
{
down(&mutex); /* enter critical region */
state[i] = HUNGRY; /* record fact that philosopher i is hungry */
test(i); /* try to acquire 2 forks */
up(&mutex); /* exit critical region */
down(&s[i]); /* block if forks were not acquired */
}
void put_forks(i) /* i: philosopher number, from 0 to N1 */
{
down(&mutex); /* enter critical region */
state[i] = THINKING; /* philosopher has finished eating */
test(LEFT); /* see if left neighbor can now eat */
test(RIGHT); /* see if right neighbor can now eat */
up(&mutex); /* exit critical region */
}
void test(i) /* i: philosopher number, from 0 to N1* /
{
if (state[i] == HUNGRY && state[LEFT] != EATING && state[RIGHT] != EATING) {
state[i] = EATING;
up(&s[i]);
}
}
The analogy is based upon a hypothetical barber shop with one barber. The barber has one barber chair
and a waiting room with a number of chairs in it. When the barber finishes cutting a customer's hair, he
dismisses the customer and then goes to the waiting room to see if there are other customers waiting. If
there are, he brings one of them back to the chair and cuts his hair. If there are no other customers
waiting, he returns to his chair and sleeps in it.
Each customer, when he arrives, looks to see what the barber is doing. If the barber is sleeping, then the
customer wakes him up and sits in the chair. If the barber is cutting hair, then the customer goes to the
waiting room. If there is a free chair in the waiting room, the customer sits in it and waits his turn. If
there is no free chair, then the customer leaves. Based on a naive analysis, the above description should
ensure that the shop functions correctly, with the barber cutting the hair of anyone who arrives until
there are no more customers, and then sleeping until the next customer arrives. In practice, there are a
number of problems that can occur that are illustrative of general scheduling problems.
The problems are all related to the fact that the actions by both the barber and the customer (checking
the waiting room, entering the shop, taking a waiting room chair, etc.) all take an unknown amount of
time. For example, a customer may arrive and observe that the barber is cutting hair, so he goes to the
waiting room. While he is on his way, the barber finishes the haircut he is doing and goes to check the
waiting room. Since there is no one there (the customer not having arrived yet), he goes back to his
chair and sleeps. The barber is now waiting for a customer and the customer is waiting for the barber.
In another example, two customers may arrive at the same time when there happens to be a single seat
in the waiting room. They observe that the barber is cutting hair, go to the waiting room, and both
attempt to occupy the single chair.
Solution:
Many possible solutions are available. The key element of each is a mutex, which ensures that only one
of the participants can change state at once. The barber must acquire this mutex exclusion before
checking for customers and release it when he begins either to sleep or cut hair. A customer must
acquire it before entering the shop and release it once he is sitting in either a waiting room chair or the
barber chair. This eliminates both of the problems mentioned in the previous section. A number of
semaphores are also required to indicate the state of the system. For example, one might store the
number of people in the waiting room.
A multiple sleeping barbers problem has the additional complexity of coordinating several barbers
among the waiting customers
Source : http://dayaramb.files.wordpress.com/2012/02/operating-system-pu.pdf