场景:

原版的故事里有五个哲学家(不过我们写的程序可以有N个哲学家),这些哲学家们只做两件事--思考和吃饭,他们思考的时候不需要任何共享资源,但是吃饭的时候就必须使用餐具,而餐桌上的餐具是有限的,原版的故事里,餐具是叉子,吃饭的时候要用两把叉子把面条从碗里捞出来。很显然把叉子换成筷子会更合理,所以:一个哲学家需要两根筷子才能吃饭。

现在引入问题的关键:这些哲学家很穷,只买得起五根筷子。他们坐成一圈,两个人的中间放一根筷子。哲学家吃饭的时候必须同时得到左手边和右手边的筷子。如果他身边的任何一位正在使用筷子,那他只有等着。

假设哲学家的编号是A、B、C、D、E,筷子编号是1、2、3、4、5,哲学家和筷子围成一圈如下图所示:

 
 

  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. int i;
  36. for(;;){
  37. usleep(3); //思考
  38. pthread_mutex_lock(&chopstick[left]); //拿起左手的筷子
  39. printf("Philosopher %c fetches chopstick %d\n", phi, left);
  40. if (pthread_mutex_trylock(&chopstick[right]) == EBUSY){ //拿起右手的筷子
  41. pthread_mutex_unlock(&chopstick[left]); //如果右边筷子被拿走放下左手的筷子
  42. continue;
  43. }
  44. //  pthread_mutex_lock(&chopstick[right]); //拿起右手的筷子,如果想观察死锁,把上一句if注释掉,再把这一句的注释去掉
  45. printf("Philosopher %c fetches chopstick %d\n", phi, right);
  46. printf("Philosopher %c is eating.\n",phi);
  47. usleep(3); //吃饭
  48. pthread_mutex_unlock(&chopstick[left]); //放下左手的筷子
  49. printf("Philosopher %c release chopstick %d\n", phi, left);
  50. pthread_mutex_unlock(&chopstick[right]); //放下左手的筷子
  51. printf("Philosopher %c release chopstick %d\n", phi, right);
  52. }
  53. }
  54. int main(){
  55. pthread_t A,B,C,D,E; //5个哲学家
  56. int i;
  57. for (i = 0; i < 5; i++)
  58. pthread_mutex_init(&chopstick[i],NULL);
  59. pthread_create(&A,NULL, eat_think, "A");
  60. pthread_create(&B,NULL, eat_think, "B");
  61. pthread_create(&C,NULL, eat_think, "C");
  62. pthread_create(&D,NULL, eat_think, "D");
  63. pthread_create(&E,NULL, eat_think, "E");
  64. pthread_join(A,NULL);
  65. pthread_join(B,NULL);
  66. pthread_join(C,NULL);
  67. pthread_join(D,NULL);
  68. pthread_join(E,NULL);
  69. return 0;
  70. }

注意:

1. gcc编译时,加上-lphread选项,例:gcc eating.c -lpthread

2.pthread_create的第四个参数是void *类型,我一开始传一个char类型,即'A',就会发生段错误。但改成char *,即“A”就没问题了。

3.usleep是毫秒级的阻塞

哲学家就餐问题 C语言实现的更多相关文章

  1. 哲学家就餐问题-Java语言实现死锁避免

    哲学家就餐问题-Java语言实现死锁避免 我死锁预防是至少破坏死锁产生的四个必要条件之一,带来的问题就是系统资源利用率低且不符合开发习惯,而死锁避免不是事先釆取某种限制措施破坏死锁的必要条件,只是注意 ...

  2. JAVA多线程学习--哲学家就餐问题

    哲学家就餐问题是1965年由Dijkstra提出的一种线程同步的问题. 问题描述:一圆桌前坐着5位哲学家,两个人中间有一只筷子,桌子中央有面条.哲学家思考问题,当饿了的时候拿起左右两只筷子吃饭,必须拿 ...

  3. JAVA并发,经典死锁案例-哲学家就餐

    转自:http://blog.csdn.net/tayanxunhua/article/details/38691005 死锁经典案例:哲学家就餐. 这个案例会导致死锁. 通过修改<Java编程 ...

  4. linux下多线程互斥量实现生产者--消费者问题和哲学家就餐问题

    生产者消费者问题,又有界缓冲区问题.两个进程共享一个一个公共的固定大小的缓冲区.其中一个是生产者,将信息放入缓冲区,另一个是消费者,从缓冲区中取信息. 问题的关键在于缓冲区已满,而此时生产者还想往其中 ...

  5. Linux环境下实现哲学家就餐问题

    #include <stdio.h> #include <stdlib.h> #include <memory.h> #include <pthread.h& ...

  6. Java多线程,哲学家就餐问题

    问题描述:一圆桌前坐着5位哲学家,两个人中间有一只筷子,桌子中央有面条.哲学家思考问题,当饿了的时候拿起左右两只筷子吃饭,必须拿到两只筷子才能吃饭.上述问题会产生死锁的情况,当5个哲学家都拿起自己右手 ...

  7. 哲学家就餐-同步问题解析-python

    五个哲学家吃五盘通心粉,由于通心粉很滑,所以必须要拿起左右两边的叉子才能吃到. 叉子的摆放如图所示. 那么问题来了:能为每一个哲学家写一段描述其行为的程序,保证不会出现死锁. 解法1:让他等待能够使用 ...

  8. Linux环境下实现哲学家就餐问题(2)

    #include <stdio.h> #include <pthread.h> #include <stdlib.h> #include <string.h& ...

  9. Go语言中的互斥锁和读写锁(Mutex和RWMutex)

    目录 一.Mutex(互斥锁) 不加锁示例 加锁示例 二.RWMutex(读写锁) 并发读示例 并发读写示例 三.死锁场景 1.Lock/Unlock不是成对出现 2.锁被拷贝使用 3.循环等待 虽然 ...

随机推荐

  1. jenkins的maven插件

    如图所示的maven项目也是一个jenkins插件:https://github.com/jenkinsci/maven-plugin 可以在插件管理里面安装:

  2. Ubuntu linux 下的基本操作

    防火墙相关: 关闭防火墙: ufw disable

  3. vue报错:Component template should contain exactly one root element. If you are using v-if on multiple elements, use v-else-if to chain them instead.

    在.vue文件中引入了 element-ui 的 table 和 pagination 组件后,报错:Component template should contain exactly one roo ...

  4. hdu 1106

    排序 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submissi ...

  5. ab webbench 网站测压解决

    ab 网站测压解决 ab –c 100 –n 100 http://192.168.1.117/forum.php (测试方式) 同时发100人发100个请求 ab –c 100 –n 1000 ht ...

  6. gcc/clang编译带pthread.h头文件的源码时需要的参数

    今天敲了一个小程序,编译时出现错误:undefined reference pthread_create 原来由于pthread库不是Linux系统默认的库,连接时需要使用库libpthread.a, ...

  7. CDH建表字符集问题

    登陆metadata数据库: show variables like 'character_set%'; alter database hivemeta default character set l ...

  8. java源码 --List、Set、Collection

    List和Set都是接口,它们继承与Collection.List是有序的队列,可以用重复的元素:而Set是数学概念中的集合,不能有重复的元素.List和Set都有它们各自的实现类. 为了方便,我们抽 ...

  9. java日志框架系列(8):logback框架PatternLayout详解

    当你想要将记录以你想要的的格式写到目的地时,那么你就需要了解如何设置自定义的格式了. 1.PatternLayout 转换模式:由文本文字和格式转换符组成. 下面了解一下格式转换符与格式修饰符表示的意 ...

  10. 使用 netkeeper 创翼电脑开 WiFi 方法(12)

    学校的宽带使用"netkeeper"联网,但是电脑依然可以开启WiFi,以下是方法: 1. Win10用户请看 2. Win7用户请看 Win7无法在"任务管理器&quo ...