您可以从 Oracle Developer Studio 开发者门户的下载区域中下载本教程所用的源文件。
在下载并解压缩样例文件之后,您可以在 OracleDeveloperStudio12.5-Samples/ThreadAnalyzer 目录中找到样例。这些样例位于 din_philo 子目录中。din_philo 目录包含了 Makefile 和 DEMO 说明文件,但是本教程并不遵循这些说明,也不使用 Makefile。本教程将逐步指导您执行命令。
为跟随本教程学习,您可以将 din_philo.c 文件从 OracleDeveloperStudio12.5-Samples/ThreadAnalyzer/din_philo 目录复制到其他目录,也可以创建自己的文件并从下面列出的代码内容中复制代码。
模拟哲学家就餐问题的 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 }