Simple dining philosopher using pthreads

user3335367 picture user3335367 · May 8, 2014 · Viewed 17.9k times · Source

I am working on the dining philosophers program. However I am running into a problem that my program stops before all of the philosophers have eaten, and I don't understand why. This is my code as of now:

#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>

void *func(int n);
pthread_t philosopher[5];
pthread_mutex_t chopstick[5];

int main()
{
     int i;
     void *msg;
     for(i=1;i<=5;i++)
     {
          pthread_mutex_init(&chopstick[i],NULL);
     }
     for(i=1;i<=5;i++)
     {
          pthread_create(&philosopher[i],NULL,(void *)func,(int *)i);
     }
     for(i=1;i<=5;i++)
     {
          pthread_join(philosopher[i],&msg);
     }
      for(i=1;i<=5;i++)
      {
          pthread_mutex_destroy(&chopstick[i]);
      }
     return 0;
}

void *func(int n)
{
     printf ("\nPhilosopher %d is thinking ",n);
     pthread_mutex_lock(&chopstick[n]);//when philosopher 5 is eating he takes fork 1 and fork 5
     pthread_mutex_lock(&chopstick[(n+1)%5]);
     printf ("\nPhilosopher %d is eating ",n);
     sleep(3);
     pthread_mutex_unlock(&chopstick[n]);
     pthread_mutex_unlock(&chopstick[(n+1)%5]);
     printf ("\nPhilosopher %d finished eating ",n);
}

Answer

Mahonri Moriancumer picture Mahonri Moriancumer · May 8, 2014

I ran the question code on my SLES 11 server many times. I did not observe the issue indicated in the question.

Nevertheless, you need to change your for() statements from:

for(i=1;i<=5;i++)

to

for(i=0;i<5;i++)

In any case, there are a few things that -might- be changed in the question code. (Nothing critical to the answer):

  • Although 'func()' is declared to return a 'void *', it does not.
  • The function prototype 'void *func(int n);' can be eliminated if 'main()' is moved to the end of the file.
  • It is not necessary to pass '&msg' into pthread_join()'; 'NULL' can be passed in instead, allowing the elimination of 'msg' completely.

Here is the code I ended up with:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

pthread_t philosopher[5];
pthread_mutex_t chopstick[5];

void *func(int n)
   {
   printf ("Philosopher %d is thinking\n",n);

   //when philosopher 5 is eating he takes fork 1 and fork 5
   pthread_mutex_lock(&chopstick[n]);
   pthread_mutex_lock(&chopstick[(n+1)%5]);
   printf ("Philosopher %d is eating\n",n);
   sleep(3);
   pthread_mutex_unlock(&chopstick[n]);
   pthread_mutex_unlock(&chopstick[(n+1)%5]);

   printf ("Philosopher %d finished eating\n",n);

   return(NULL);
   }

int main()
   {
   int i;
   for(i=0;i<5;i++)
      pthread_mutex_init(&chopstick[i],NULL);

   for(i=0;i<5;i++)
      pthread_create(&philosopher[i],NULL,(void *)func,(void *)i);

   for(i=0;i<5;i++)
      pthread_join(philosopher[i],NULL);

   for(i=0;i<5;i++)
      pthread_mutex_destroy(&chopstick[i]);

   return 0;
   }