/* philosophers.c * Simulate the dining philosophers problem with POSIX threads. * This uses asymmetry to make a deadlock-free solution. * gcc -o philosophers -lpthread philosophers.c */ #include #include #include #include // has pthreads types #include "pthread.h" // constants #define NUM_PHILOSOPHERS 5 // global variables int err; int phil_ids[NUM_PHILOSOPHERS]; pthread_mutex_t chopsticks[NUM_PHILOSOPHERS]; // thread's main function void *philosopher(void *arg) { int i; int id = *(int *)arg; int first = id-1; if (first < 0) first = NUM_PHILOSOPHERS-1; int second = id; // Break the symmetry. If this is commented out, then the simulation // is subject to deadlock. We are more likely to encounter the deadlock // if the sleep commands are commented out. // if (id==0) // { // // I'm the odd philosopher out // first = id; // second = NUM_PHILOSOPHERS-1; // } for (i = 0; i < 1000; i++) // lots of meals :) { // sleep to simulate thinking // sleep(1*(rand()%4+1)); // think between 1 and 4 seconds // eat pthread_mutex_lock(&chopsticks[first]); pthread_mutex_lock(&chopsticks[second]); printf("Philosopher %i dining\n",id); // sleep to simulate eating // sleep(1*(rand()%3+1)); // eat between 1 and 3 seconds pthread_mutex_unlock(&chopsticks[first]); pthread_mutex_unlock(&chopsticks[second]); } // end for loop return NULL; } // end philospoher function // main function int main(int argc, char *argv[]) { pthread_t tid[NUM_PHILOSOPHERS]; int i; for (i = 0; i < NUM_PHILOSOPHERS; i++) pthread_mutex_init(&chopsticks[i],NULL); for (i = 0; i < NUM_PHILOSOPHERS; i++) { phil_ids[i] = i; err = pthread_create(&tid[i],NULL,philosopher,&phil_ids[i]); } for (i = 0; i < NUM_PHILOSOPHERS; i++) { err = pthread_join(tid[i], NULL); } for (i = 0; i < NUM_PHILOSOPHERS; i++) pthread_mutex_destroy(&chopsticks[i]); }