concurrencysemaphoredining-philosopherbinary-semaphore

Dining philosophers using binary semaphores


Can this pseudocode solve the dining philosopher problem with maximum parallelism? Here mutex is a binary semaphore initialized to 1. Forks are assumed to be numbered from 0 to (N-1). There are a total of N philosophers numbered from 0 to (N-1).

void philosopher(int i)    // ith philosopher
{   
   while (true)
   {
        think();
        down(&mutex);          // acquire lock
        take_fork(i);            // take left fork
        take_fork((i+1)%N);        // take right fork
        up(&mutex);          // release the lock
        eat();
        down(&mutex);       // acquire lock
        put_fork(i);
        put_fork((i+1)%N);
        up(&mutex);        // release the lock
   }    
}

This should solve the dining philosopher problem with maximum parallelism, because the lock is released after one philosopher has acquired both forks. But will it? And will there be any issue of liveliness? I am confused.


Solution

  • To answer your question I would like to provide a trace of events that seems to lead your philosophers into an undesired state.

    Consider a system with N>2 philosophers Ph(0),...,Ph(N-1) and the following sequence of actions:

    Ph(1).think();
    Ph(0).think();
    Ph(1).down(&mutex);
    Ph(1).take_fork(1);
    Ph(1).take_fork(2);
    Ph(1).up(&mutex);
    Ph(0).down(&mutex);
    Ph(0).take_fork(0);
    Ph(0).take_fork(1);
    

    Recall that fork(1) is already acquired by Ph(1). Now depending on the semantics of take_fork() different behavior can occur.

    If take_fork() fails immediately if the fork cannot be acquired, then fork(0) would never be released.

    If take_fork() hangs until the resource is released, then the mutex would never be released and none of the other philosophers would be able to make progress therefore only one philosopher will be eating at a time.