Dining Philosopher\'s problem: Five silent philosophers sit at a round table wit
ID: 3728513 • Letter: D
Question
Dining Philosopher's problem:
Five silent philosophers sit at a round table with bowls of spaghetti. Forks are placed between each pair of adjacent philosophers.
Each philosopher must alternately think and eat. However, a philosopher can only eat spaghetti when they have both left and right forks. Each fork can be held by only one philosopher and so a philosopher can use the fork only if it is not being used by another philosopher. After an individual philosopher finishes eating, they need to put down both forks so that the forks become available to others. A philosopher can take the fork on their right or the one on their left as they become available, but cannot start eating before getting both forks.
Begin by creating 5 philosophers, each identified by a number from 0 to 4. Each philosopher runs as a seperate thread. Philosophers alternate between thinking and eating. In order to simulate these activities each thread will sleep between 1 to 3 seconds.
In order to eat the philosopher invokes the function pickup_forks (int philosopher_number)
When the philosopher is done eating they invoke the function return_forks(int philosopher_number);
Pthread Condition Variable:
The following condition/mutex variables/functions must be included in your code:
pthread_mutex_t mutex;
pthread_cond_t cond_var;
pthread_mutex_init(&mutex, NULL);
pthread_cond_init(&cond_var, NULL);
pthread_cond_wait(&cond_var, &mutex);
pthread_cond_signal(&cond_var);
pthread_mutex_lock(&mutex);
pthread_mutex_unlock(&mutex);
Below is some code to help you get started:
Explanation / Answer
The code in C is as follows, use -lpthread to compile it
gcc mycode.c -lpthread
CODE
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
void *dine(void *);
int chopsticks[5];
pthread_mutex_t mutex;
pthread_cond_t cond[5]; //one for each philosopher
int main(int argc, char *argv[])
{
int i, rc;
pthread_mutex_init(&mutex, NULL);
pthread_t philsophers[5];
srand(time(NULL));
/* Initialize chopsticks and cond vars */
for (i=0; i<5; ++i)
{
pthread_cond_init(&cond[i], NULL);
chopsticks[i]=0;
}
/* Spawn threads */
for (i=0; i<5; ++i)
{
if( (rc=pthread_create( &philsophers[i], NULL, dine, &i)) )
printf("Thread creation failed: %d ", rc);
sleep(1);
}
/* Wait for thread completion */
for (i=0; i<5; ++i)
pthread_join( philsophers[i], NULL);
exit(0);
}
void think(int pnum)
{
printf("philosopher %d is thinking ", pnum);
}
void eat(int pnum)
{
pthread_mutex_lock(&mutex);
//if chopstick isnt available, unlock the mutex and wait for chopstick
if(chopsticks[pnum])
pthread_cond_wait(&cond[pnum], &mutex);
printf("philosopher %d picked left chopstick ", pnum);
chopsticks[pnum] = 1;
//if chopstick isnt available, unlock the mutex and wait for chopstick
if(chopsticks[(pnum + 1) % 5])
pthread_cond_wait(&cond[(pnum + 1) % 5], &mutex);
printf("philosopher %d picked right chopstick ", pnum);
chopsticks[(pnum + 1) % 5] = 1;
//lets use the chopsticks
printf("philosopher %d is eating ", pnum);
//done using
chopsticks[pnum] = 0;
chopsticks[(pnum + 1) % 5] = 0;
printf("philosopher %d put both chopsticks down ", pnum);
pthread_cond_signal(&cond[pnum]);
pthread_cond_signal(&cond[(pnum + 1) % 5]);
pthread_mutex_unlock(&mutex);
}
void *dine(void *pnum_ptr)
{
int pnum = *(int*)pnum_ptr;
printf("Created philosopher thread %d ", pnum);
while (1)
{
think(pnum);
sleep(rand() % 3 + 1); //wait for 1 or 2 or 3 seconds
eat(pnum);
sleep(rand() % 3 + 1);
}
}
Sample Output
Created philosopher thread 0
philosopher 0 is thinking
philosopher 0 picked left chopstick
philosopher 0 picked right chopstick
philosopher 0 is eating
philosopher 0 put both chopsticks down
Created philosopher thread 1
philosopher 1 is thinking
Created philosopher thread 2
philosopher 2 is thinking
Created philosopher thread 3
philosopher 3 is thinking
philosopher 0 is thinking
philosopher 2 picked left chopstick
philosopher 2 picked right chopstick
philosopher 2 is eating
philosopher 2 put both chopsticks down
philosopher 1 picked left chopstick
philosopher 1 picked right chopstick
philosopher 1 is eating
philosopher 1 put both chopsticks down
philosopher 3 picked left chopstick
philosopher 3 picked right chopstick
philosopher 3 is eating
philosopher 3 put both chopsticks down
Created philosopher thread 4
philosopher 4 is thinking
philosopher 0 picked left chopstick
philosopher 0 picked right chopstick
philosopher 0 is eating
philosopher 0 put both chopsticks down
philosopher 1 is thinking
philosopher 0 is thinking
philosopher 2 is thinking
philosopher 4 picked left chopstick
philosopher 4 picked right chopstick
philosopher 4 is eating
philosopher 4 put both chopsticks down
philosopher 3 is thinking
philosopher 1 picked left chopstick
philosopher 1 picked right chopstick
philosopher 1 is eating
philosopher 1 put both chopsticks down
philosopher 3 picked left chopstick
philosopher 3 picked right chopstick
philosopher 3 is eating
philosopher 3 put both chopsticks down
philosopher 0 picked left chopstick
philosopher 0 picked right chopstick
philosopher 0 is eating
philosopher 0 put both chopsticks down
philosopher 2 picked left chopstick
philosopher 2 picked right chopstick
philosopher 2 is eating
philosopher 2 put both chopsticks down
philosopher 4 is thinking
philosopher 1 is thinking
philosopher 4 picked left chopstick
philosopher 4 picked right chopstick
philosopher 4 is eating
philosopher 4 put both chopsticks down
philosopher 3 is thinking
philosopher 0 is thinking
philosopher 2 is thinking
philosopher 2 picked left chopstick
philosopher 2 picked right chopstick
philosopher 2 is eating
philosopher 2 put both chopsticks down
philosopher 1 picked left chopstick
philosopher 1 picked right chopstick
philosopher 1 is eating
philosopher 1 put both chopsticks down
philosopher 3 picked left chopstick
philosopher 3 picked right chopstick
philosopher 3 is eating
philosopher 3 put both chopsticks down
philosopher 4 is thinking
philosopher 1 is thinking