您可以从 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 }