このチュートリアルで使用するソースファイルは、Oracle Developer Studio 開発者ポータルのダウンロードエリアからダウンロードできます。
サンプルファイルをダウンロードして展開したあと、OracleDeveloperStudio12.5-Samples/ThreadAnalyzer ディレクトリからサンプルを見つけることができます。サンプルは din_philo サブディレクトリにあります。din_philo ディレクトリには、手順に関する DEMO ファイルと Makefile ファイルが 1 つずつありますが、このチュートリアルではそれらの手順に従わず、Makefile も使用しません。代わりに、コマンドを個別に実行していきます。
このチュートリアルに従うには、OracleDeveloperStudio12.5-Samples/ThreadAnalyzer/din_philo ディレクトリから din_philo.c ファイルを別のディレクトリにコピーするか、個々にファイルを作成し、次のコードリストからコードをコピーしてください。
食事する哲学者の問題をシミュレートする din_philo.c サンプルプログラムは、POSIX スレッドを使用する C プログラムです。このプログラムでは、潜在的デッドロックと実デッドロックの両方が示されます。
din_philo.c のソースコードは次に示すとおりです。
1 /*
2 * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All Rights Reserved.
3 */
4
5 #include <pthread.h>
6 #include <stdio.h>
7 #include <unistd.h>
8 #include <stdlib.h>
9 #include <errno.h>
10 #include <assert.h>
11
12 #define PHILOS 5
13 #define DELAY 5000
14 #define FOOD 100
15
16 void *philosopher (void *id);
17 void grab_chopstick (int,
18 int,
19 char *);
20 void down_chopsticks (int,
21 int);
22 int food_on_table ();
23
24 pthread_mutex_t chopstick[PHILOS];
25 pthread_t philo[PHILOS];
26 pthread_mutex_t food_lock;
27 int sleep_seconds = 0;
28
29
30 int
31 main (int argn,
32 char **argv)
33 {
34 int i;
35
36 if (argn == 2)
37 sleep_seconds = atoi (argv[1]);
38
39 pthread_mutex_init (&food_lock, NULL);
40 for (i = 0; i < PHILOS; i++)
41 pthread_mutex_init (&chopstick[i], NULL);
42 for (i = 0; i < PHILOS; i++)
43 pthread_create (&philo[i], NULL, philosopher, (void *)i);
44 for (i = 0; i < PHILOS; i++)
45 pthread_join (philo[i], NULL);
46 return 0;
47 }
48
49 void *
50 philosopher (void *num)
51 {
52 int id;
53 int i, left_chopstick, right_chopstick, f;
54
55 id = (int)num;
56 printf ("Philosopher %d is done thinking and now ready to eat.\n", id);
57 right_chopstick = id;
58 left_chopstick = id + 1;
59
60 /* Wrap around the chopsticks. */
61 if (left_chopstick == PHILOS)
62 left_chopstick = 0;
63
64 while (f = food_on_table ()) {
65
66 /* Thanks to philosophers #1 who would like to take a nap
67 * before picking up the chopsticks, the other philosophers
68 * may be able to eat their dishes and not deadlock.
69 */
70 if (id == 1)
71 sleep (sleep_seconds);
72
73 grab_chopstick (id, right_chopstick, "right ");
74 grab_chopstick (id, left_chopstick, "left");
75
76 printf ("Philosopher %d: eating.\n", id);
77 usleep (DELAY * (FOOD - f + 1));
78 down_chopsticks (left_chopstick, right_chopstick);
79 }
80
81 printf ("Philosopher %d is done eating.\n", id);
82 return (NULL);
83 }
84
85 int
86 food_on_table ()
87 {
88 static int food = FOOD;
89 int myfood;
90
91 pthread_mutex_lock (&food_lock);
92 if (food > 0) {
93 food--;
94 }
95 myfood = food;
96 pthread_mutex_unlock (&food_lock);
97 return myfood;
98 }
99
100 void
101 grab_chopstick (int phil,
102 int c,
103 char *hand)
104 {
105 pthread_mutex_lock (&chopstick[c]);
106 printf ("Philosopher %d: got %s chopstick %d\n", phil, hand, c);
107 }
108
109 void
110 down_chopsticks (int c1,
111 int c2)
112 {
113 pthread_mutex_unlock (&chopstick[c1]);
114 pthread_mutex_unlock (&chopstick[c2]);
115 }