The sample program which simulates the dining-philosophers problem is a C program that uses POSIX threads. The source file is called din_philo.c. The program can exhibit both potential and actual deadlocks. Here is the listing of the code which is followed by an explanation:
/* din_philo.c */
1 #include <pthread.h>
2 #include <stdio.h>
3 #include <unistd.h>
4 #include <stdlib.h>
5 #include <errno.h>
6 #include <assert.h>
7
8 #define PHILOS 5
9 #define DELAY 5000
10 #define FOOD 50
11
12 void *philosopher (void *id);
13 void grab_chopstick (int,
14 int,
15 char *);
16 void down_chopsticks (int,
17 int);
18 int food_on_table ();
19
20 pthread_mutex_t chopstick[PHILOS];
21 pthread_t philo[PHILOS];
22 pthread_mutex_t food_lock;
23 int sleep_seconds = 0;
24
25
26 int
27 main (int argn,
28 char **argv)
29 {
30 int i;
31
32 if (argn == 2)
33 sleep_seconds = atoi (argv[1]);
34
35 pthread_mutex_init (&food_lock, NULL);
36 for (i = 0; i < PHILOS; i++)
37 pthread_mutex_init (&chopstick[i], NULL);
38 for (i = 0; i < PHILOS; i++)
39 pthread_create (&philo[i], NULL, philosopher, (void *)i);
40 for (i = 0; i < PHILOS; i++)
41 pthread_join (philo[i], NULL);
42 return 0;
43 }
44
45 void *
46 philosopher (void *num)
47 {
48 int id;
49 int i, left_chopstick, right_chopstick, f;
50
51 id = (int)num;
52 printf ("Philosopher %d is done thinking and now ready to eat.\n", id);
53 right_chopstick = id;
54 left_chopstick = id + 1;
55
56 /* Wrap around the chopsticks. */
57 if (left_chopstick == PHILOS)
58 left_chopstick = 0;
59
60 while (f = food_on_table ()) {
61
62 /* Thanks to philosophers #1 who would like to take a nap
63 * before picking up the chopsticks, the other philosophers
64 * may be able to eat their dishes and not deadlock.
65 */
66 if (id == 1)
67 sleep (sleep_seconds);
68
69 grab_chopstick (id, right_chopstick, "right ");
70 grab_chopstick (id, left_chopstick, "left");
71
72 printf ("Philosopher %d: eating.\n", id);
73 usleep (DELAY * (FOOD - f + 1));
74 down_chopsticks (left_chopstick, right_chopstick);
75 }
76
77 printf ("Philosopher %d is done eating.\n", id);
78 return (NULL);
79 }
80
81 int
82 food_on_table ()
83 {
84 static int food = FOOD;
85 int myfood;
86
87 pthread_mutex_lock (&food_lock);
88 if (food > 0) {
89 food--;
90 }
91 myfood = food;
92 pthread_mutex_unlock (&food_lock);
93 return myfood;
94 }
95
96 void
97 grab_chopstick (int phil,
98 int c,
99 char *hand)
100 {
101 pthread_mutex_lock (&chopstick[c]);
102 printf ("Philosopher %d: got %s chopstick %d\n", phil, hand, c);
103 }
104
105 void
106 down_chopsticks (int c1,
107 int c2)
108 {
109 pthread_mutex_unlock (&chopstick[c1]);
110 pthread_mutex_unlock (&chopstick[c2]);
111 }