哲学家就餐问题C语言实现

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

哲学家就餐问题C语⾔实现
场景:
原版的故事⾥有五个哲学家(不过我们写的程序可以有N个哲学家),这些哲学家们只做两件事--思考和吃饭,他们思考的时候不需要任何共享资源,但是吃饭的时候就必须使⽤餐具,⽽餐桌上的餐具是有限的,原版的故事⾥,餐具是叉⼦,吃饭的时候要⽤两把叉⼦把⾯条从碗⾥捞出来。

很显然把叉⼦换成筷⼦会更合理,所以:⼀个哲学家需要两根筷⼦才能吃饭。

现在引⼊问题的关键:这些哲学家很穷,只买得起五根筷⼦。

他们坐成⼀圈,两个⼈的中间放⼀根筷⼦。

哲学家吃饭的时候必须同时得到左⼿边和右⼿边的筷⼦。

如果他⾝边的任何⼀位正在使⽤筷⼦,那他只有等着。

假设哲学家的编号是A、B、C、D、E,筷⼦编号是1、2、3、4、5,哲学家和筷⼦围成⼀圈如下图所⽰:
[cpp]
1. #include <stdio.h>
2. #include <stdlib.h>
3. #include <memory.h>
4. #include <pthread.h>
5. #include <errno.h>
6. #include <math.h>
7. //筷⼦作为mutex
8. pthread_mutex_t chopstick[6] ;
9. void *eat_think(void *arg)
10. {
11. char phi = *(char *)arg;
12. int left,right; //左右筷⼦的编号
13. switch (phi){
14. case 'A':
15. left = 5;
16. right = 1;
17. break;
18. case 'B':
19. left = 1;
20. right = 2;
21. break;
22. case 'C':
23. left = 2;
24. right = 3;
25. break;
26. case 'D':
27. left = 3;
28. right = 4;
29. break;
30. case 'E':
31. left = 4;
32. right = 5;
33. break;
34. }
35.
36. int i;
37. for(;;){
38. usleep(3); //思考
39. pthread_mutex_lock(&chopstick[left]); //拿起左⼿的筷⼦
40. printf("Philosopher %c fetches chopstick %d\n", phi, left);
41. if (pthread_mutex_trylock(&chopstick[right]) == EBUSY){ //拿起右⼿的筷⼦
42. pthread_mutex_unlock(&chopstick[left]); //如果右边筷⼦被拿⾛放下左⼿的筷⼦
43. continue;
44. }
45.
46. // pthread_mutex_lock(&chopstick[right]); //拿起右⼿的筷⼦,如果想观察死锁,把上⼀句if注释掉,再把这⼀句的注释去掉
47. printf("Philosopher %c fetches chopstick %d\n", phi, right);
48. printf("Philosopher %c is eating.\n",phi);
49. usleep(3); //吃饭
50. pthread_mutex_unlock(&chopstick[left]); //放下左⼿的筷⼦
51. printf("Philosopher %c release chopstick %d\n", phi, left);
52. pthread_mutex_unlock(&chopstick[right]); //放下左⼿的筷⼦
53. printf("Philosopher %c release chopstick %d\n", phi, right);
54.
55. }
56. }
57. int main(){
58. pthread_t A,B,C,D,E; //5个哲学家
59.
60. int i;
61. for (i = 0; i < 5; i++)
62. pthread_mutex_init(&chopstick[i],NULL);
63. pthread_create(&A,NULL, eat_think, "A");
64. pthread_create(&B,NULL, eat_think, "B");
65. pthread_create(&C,NULL, eat_think, "C");
66. pthread_create(&D,NULL, eat_think, "D");
67. pthread_create(&E,NULL, eat_think, "E");
68.
69. pthread_join(A,NULL);
70. pthread_join(B,NULL);
71. pthread_join(C,NULL);
72. pthread_join(D,NULL);
73. pthread_join(E,NULL);
74. return 0;
75. }
注意:
1. gcc编译时,加上-lphread选项,例:gcc eating.c -lpthread
2.pthread_create的第四个参数是void *类型,我⼀开始传⼀个char类型,即'A',就会发⽣段错误。

但改成char *,即“A”就没问题了。

leep是毫秒级的阻塞。

相关文档
最新文档