I am a beginner and I was implementing Dining Philosopher's problem. However, I ran across an issue. In my philosopher() function, I want my other threads to wait till the right and left chopsticks are available for them to use. How should I implement this? Currently, the program simply terminates after 2 philosophers are done eating without waiting for the others to eat
I've already tried :
- Using mutex to lock the shared variables in the philosopher() function and although it makes sure that no philosopher goes hungry, using this approach means giving up concurrency (only one philosopher can eat at a time even though there are chopsticks available for other philosophers to use)
- Using sleep() function in my while-loop but it doesn't work either
Any help is appreciated, thanks!
CODE
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
#include <stdlib.h>
#define NUM 5 // Number of Philosophers
sem_t chopSticks[NUM]; // binary semaphore for each chopstick
sem_t mutex;
int philNo[NUM] = {0, 1, 2, 3, 4};
void* philosopher(void*);
int main()
{
int semValue;
pthread_t threadId[NUM]; // 5 concurrent threads for 5 philsophers
sem_init(&mutex, 0, 1);
for(int i=0; i< NUM; i++)
sem_init(&chopSticks[i], 0, 1);
for(int i=0; i< NUM; i++)
{
pthread_create(&threadId[i], NULL, philosopher, (void*) &philNo[i]);
printf("\nPhilosopher %d is thinking", i+1);
}
for(int i=0; i< NUM; i++)
pthread_join(threadId[i], NULL);
return 0;
}
void* philosopher(void* philNo)
{
int n = *(int*) philNo;
int rightValue, leftValue;
int left = (n+4) % NUM;
int right = (n+1) % NUM;
sem_getvalue(&chopSticks[left], &leftValue);
sem_getvalue(&chopSticks[right], &rightValue);
//sem_wait(&mutex);
/* while(leftValue != 1 && rightValue != 1)
{
wait for the left and right chopsticks to be free
How should I implement this?
} */
if(leftValue == 1 && rightValue == 1) // if both left and right chopSticks are free then start eating
{
sem_wait(&chopSticks[left]);
sem_wait(&chopSticks[right]);
printf("\nPhilosopher %d has taken Chopstick-%d and Chopstick-%d", n+1, left+1, right+1);
printf("\nPhilosopher %d is Eating", n+1);
sleep(1);
sem_post(&chopSticks[left]);
sem_post(&chopSticks[right]);
printf("\nPhilosopher %d finished eating", n+1);
printf("\nPhilosopher %d has put down chopstick-%d and chopstick-%d", n+1, left+1, right+1);
}
//sem_post(&mutex);
}
You can not have sempahore per fork on the dining table. This is the classic mistake that will lead you to the deadlock situation. Imagine all the philosophers simultaneously pick up the left fork your sempahore implementation will allow that, but after that point no one will be able to pick up the right fork, because none is available and all threads will indefinitely block.
The only solution that will work is a philosopher will not pickup any fork till both the left & right hand forks are available (i.e. neither neighbor is eating at the same time.)
The philosopher’s routine is: 0. Each philosopher will have state associated with her. The state is referred by the neighbours to find out what the philosopher is doing.
Pseudo oop code is as below:
Check out link below: https://codeistry.wordpress.com/2018/04/06/dinning-philosophers-problem/