patterncMinor
Dining philosophers problem with mutexes
Viewed 0 times
problemphilosophersdiningwithmutexes
Problem
I know this dining philosophers problem has been researched a lot and there are resources everywhere. But I wrote simple code to solve this problem with C and then turned to the Internet to see if it's correct. I wrote this with mutexes only and almost all implementations on the Internet use a semaphore. Now I'm not sure about my code.
```
#include
#include
#include
#include
#define NO_OF_PHILOSOPHERS 5
pthread_t philosophers[NO_OF_PHILOSOPHERS];
pthread_mutex_t mutex_forks = PTHREAD_MUTEX_INITIALIZER;;
int forks[NO_OF_PHILOSOPHERS];
void init()
{
int i;
for(i=0; i<NO_OF_PHILOSOPHERS; i++)
forks[i] = 0;
}
void philosopher(int i)
{
int right = i;
int left = (i - 1 == -1) ? NO_OF_PHILOSOPHERS - 1 : (i - 1);
int locked;
while(1)
{
locked = 0;
while(!locked)
{
pthread_mutex_lock(&mutex_forks);
if(forks[right] || forks[left])
{
pthread_mutex_unlock(&mutex_forks); // give up the forks unless you can take both at once.
printf("Philosopher %d cannot take forks. Giving up and thinking.\n",i);
usleep(random() % 1000); // think.
continue;
}
forks[right] = 1; // take forks.
forks[left] = 1;
pthread_mutex_unlock(&mutex_forks);
locked = 1;
}
printf("Philosopher %d took both forks. Now eating :)\n",i);
usleep(random() % 500);
printf("Philosopher %d done with eating. Giving up forks.\n",i);
pthread_mutex_lock(&mutex_forks); // give up forks.
forks[right] = 0;
forks[left] = 0;
pthread_mutex_unlock(&mutex_forks);
usleep(random() % 1000);
}
}
int main()
{
init();
int i;
for(i=0; i<NO_OF_PHILOSOPHERS; i++)
pthread_create( &philosophers[i], NULL, philosopher, (void*)i);
for(i=0; i<NO
```
#include
#include
#include
#include
#define NO_OF_PHILOSOPHERS 5
pthread_t philosophers[NO_OF_PHILOSOPHERS];
pthread_mutex_t mutex_forks = PTHREAD_MUTEX_INITIALIZER;;
int forks[NO_OF_PHILOSOPHERS];
void init()
{
int i;
for(i=0; i<NO_OF_PHILOSOPHERS; i++)
forks[i] = 0;
}
void philosopher(int i)
{
int right = i;
int left = (i - 1 == -1) ? NO_OF_PHILOSOPHERS - 1 : (i - 1);
int locked;
while(1)
{
locked = 0;
while(!locked)
{
pthread_mutex_lock(&mutex_forks);
if(forks[right] || forks[left])
{
pthread_mutex_unlock(&mutex_forks); // give up the forks unless you can take both at once.
printf("Philosopher %d cannot take forks. Giving up and thinking.\n",i);
usleep(random() % 1000); // think.
continue;
}
forks[right] = 1; // take forks.
forks[left] = 1;
pthread_mutex_unlock(&mutex_forks);
locked = 1;
}
printf("Philosopher %d took both forks. Now eating :)\n",i);
usleep(random() % 500);
printf("Philosopher %d done with eating. Giving up forks.\n",i);
pthread_mutex_lock(&mutex_forks); // give up forks.
forks[right] = 0;
forks[left] = 0;
pthread_mutex_unlock(&mutex_forks);
usleep(random() % 1000);
}
}
int main()
{
init();
int i;
for(i=0; i<NO_OF_PHILOSOPHERS; i++)
pthread_create( &philosophers[i], NULL, philosopher, (void*)i);
for(i=0; i<NO
Solution
In the problem as I have seen it, the philosophers only take one fork at a time and can hang on to it (but they only eat when they have 2 forks). You have simplified it by having them take both or none.
There shouldn't be any deadlocks as the philosopher only has 0 or 2 forks, but there is still potential for starvation if the 2 neighbouring philosophers start eating again before the philosopher has finished thinking.
There shouldn't be any deadlocks as the philosopher only has 0 or 2 forks, but there is still potential for starvation if the 2 neighbouring philosophers start eating again before the philosopher has finished thinking.
Context
StackExchange Code Review Q#26618, answer score: 3
Revisions (0)
No revisions yet.