哲学家就餐问题 C语言实现
场景:
原版的故事里有五个哲学家(不过我们写的程序可以有N个哲学家),这些哲学家们只做两件事--思考和吃饭,他们思考的时候不需要任何共享资源,但是吃饭的时候就必须使用餐具,而餐桌上的餐具是有限的,原版的故事里,餐具是叉子,吃饭的时候要用两把叉子把面条从碗里捞出来。很显然把叉子换成筷子会更合理,所以:一个哲学家需要两根筷子才能吃饭。
现在引入问题的关键:这些哲学家很穷,只买得起五根筷子。他们坐成一圈,两个人的中间放一根筷子。哲学家吃饭的时候必须同时得到左手边和右手边的筷子。如果他身边的任何一位正在使用筷子,那他只有等着。
假设哲学家的编号是A、B、C、D、E,筷子编号是1、2、3、4、5,哲学家和筷子围成一圈如下图所示:

- #include <stdio.h>
- #include <stdlib.h>
- #include <memory.h>
- #include <pthread.h>
- #include <errno.h>
- #include <math.h>
- //筷子作为mutex
- pthread_mutex_t chopstick[6] ;
- void *eat_think(void *arg)
- {
- char phi = *(char *)arg;
- int left,right; //左右筷子的编号
- switch (phi){
- case 'A':
- left = 5;
- right = 1;
- break;
- case 'B':
- left = 1;
- right = 2;
- break;
- case 'C':
- left = 2;
- right = 3;
- break;
- case 'D':
- left = 3;
- right = 4;
- break;
- case 'E':
- left = 4;
- right = 5;
- break;
- }
- int i;
- for(;;){
- usleep(3); //思考
- pthread_mutex_lock(&chopstick[left]); //拿起左手的筷子
- printf("Philosopher %c fetches chopstick %d\n", phi, left);
- if (pthread_mutex_trylock(&chopstick[right]) == EBUSY){ //拿起右手的筷子
- pthread_mutex_unlock(&chopstick[left]); //如果右边筷子被拿走放下左手的筷子
- continue;
- }
- // pthread_mutex_lock(&chopstick[right]); //拿起右手的筷子,如果想观察死锁,把上一句if注释掉,再把这一句的注释去掉
- printf("Philosopher %c fetches chopstick %d\n", phi, right);
- printf("Philosopher %c is eating.\n",phi);
- usleep(3); //吃饭
- pthread_mutex_unlock(&chopstick[left]); //放下左手的筷子
- printf("Philosopher %c release chopstick %d\n", phi, left);
- pthread_mutex_unlock(&chopstick[right]); //放下左手的筷子
- printf("Philosopher %c release chopstick %d\n", phi, right);
- }
- }
- int main(){
- pthread_t A,B,C,D,E; //5个哲学家
- int i;
- for (i = 0; i < 5; i++)
- pthread_mutex_init(&chopstick[i],NULL);
- pthread_create(&A,NULL, eat_think, "A");
- pthread_create(&B,NULL, eat_think, "B");
- pthread_create(&C,NULL, eat_think, "C");
- pthread_create(&D,NULL, eat_think, "D");
- pthread_create(&E,NULL, eat_think, "E");
- pthread_join(A,NULL);
- pthread_join(B,NULL);
- pthread_join(C,NULL);
- pthread_join(D,NULL);
- pthread_join(E,NULL);
- return 0;
- }
注意:
1. gcc编译时,加上-lphread选项,例:gcc eating.c -lpthread
2.pthread_create的第四个参数是void *类型,我一开始传一个char类型,即'A',就会发生段错误。但改成char *,即“A”就没问题了。
3.usleep是毫秒级的阻塞
哲学家就餐问题 C语言实现的更多相关文章
- 哲学家就餐问题-Java语言实现死锁避免
哲学家就餐问题-Java语言实现死锁避免 我死锁预防是至少破坏死锁产生的四个必要条件之一,带来的问题就是系统资源利用率低且不符合开发习惯,而死锁避免不是事先釆取某种限制措施破坏死锁的必要条件,只是注意 ...
- JAVA多线程学习--哲学家就餐问题
哲学家就餐问题是1965年由Dijkstra提出的一种线程同步的问题. 问题描述:一圆桌前坐着5位哲学家,两个人中间有一只筷子,桌子中央有面条.哲学家思考问题,当饿了的时候拿起左右两只筷子吃饭,必须拿 ...
- JAVA并发,经典死锁案例-哲学家就餐
转自:http://blog.csdn.net/tayanxunhua/article/details/38691005 死锁经典案例:哲学家就餐. 这个案例会导致死锁. 通过修改<Java编程 ...
- linux下多线程互斥量实现生产者--消费者问题和哲学家就餐问题
生产者消费者问题,又有界缓冲区问题.两个进程共享一个一个公共的固定大小的缓冲区.其中一个是生产者,将信息放入缓冲区,另一个是消费者,从缓冲区中取信息. 问题的关键在于缓冲区已满,而此时生产者还想往其中 ...
- Linux环境下实现哲学家就餐问题
#include <stdio.h> #include <stdlib.h> #include <memory.h> #include <pthread.h& ...
- Java多线程,哲学家就餐问题
问题描述:一圆桌前坐着5位哲学家,两个人中间有一只筷子,桌子中央有面条.哲学家思考问题,当饿了的时候拿起左右两只筷子吃饭,必须拿到两只筷子才能吃饭.上述问题会产生死锁的情况,当5个哲学家都拿起自己右手 ...
- 哲学家就餐-同步问题解析-python
五个哲学家吃五盘通心粉,由于通心粉很滑,所以必须要拿起左右两边的叉子才能吃到. 叉子的摆放如图所示. 那么问题来了:能为每一个哲学家写一段描述其行为的程序,保证不会出现死锁. 解法1:让他等待能够使用 ...
- Linux环境下实现哲学家就餐问题(2)
#include <stdio.h> #include <pthread.h> #include <stdlib.h> #include <string.h& ...
- Go语言中的互斥锁和读写锁(Mutex和RWMutex)
目录 一.Mutex(互斥锁) 不加锁示例 加锁示例 二.RWMutex(读写锁) 并发读示例 并发读写示例 三.死锁场景 1.Lock/Unlock不是成对出现 2.锁被拷贝使用 3.循环等待 虽然 ...
随机推荐
- iOS-AVFoundation生成缩略图
使用MPMoviePlayerController来生成缩略图足够简单,但是如果仅仅是是为了生成缩略图而不进行视频播放的话,此刻使用 MPMoviePlayerController就有点大材小用了.其 ...
- 如何区分进程和线程ps -eLf
方式 使用ls /proc/pid/task/ 查看线程 使用ps -eLf命令/ps aux -L/ps aux -el 使用pstree 进程和线程 进程是资源分配的最小单位 线程是cpu时间片分 ...
- 🔥Scratch少儿编程——飞机大战
前两天用
- python+unittest框架第一天unittest之简单认识Test Fixure:测试固件【8月17更新】
20万的慢慢会实现的吧,hhh unittest框架,我就不在介绍了,百度有很详细的介绍. 我们只要了解: 1.unittest是单元测试框架 2.它提供用例组织与执行:在实际工作中案例可能有上百条, ...
- 【转帖】计算机网络协议(三)——UDP、TCP、Socket
计算机网络协议(三)——UDP.TCP.Socket 2019年09月04日 11:09:41 to_be_better_one 阅读数 28794 文章标签: 计算机网络UDPTCPSocket 更 ...
- 小程序使用mpvue框架无缝接入Vant Weapp组件库
有美团开源出的mpvue以其vue的语法和良好的开发效率再搭配上用户体验良好的UI组件无疑是定制化微信小程序的开发方式,然而由于mpvue是对微信原生开发的再次封装,这也为我们引入UI组件添加了不少麻 ...
- centos 7.2安装git2.x版本
前言 今天在我的centos7.2开发环境安装git2.x时候遇到了各种问题,还好一一解决,为方便大家,这里列出遇到的问题和解决办法,yum默认安装的git1.8版本的,公司git服务器在window ...
- 基于requests模块的代理
1.什么是代理? 代理:将网络请求发送给代理服务器,通过代理服务器做中介,将请求转发给目标服务器并将响应返回,从而完成网络通信. 2.为什么使用代理? 使用爬虫抓取批量资源时,在短时间内会对服 ...
- python学习-17 列表list 2
# 1. 选择嵌套列表里的元素(内部进行了for循环) li = [1,2,",45]],"abc",True] a = li[3][2][1] print(a) 运行结 ...
- 【C#】课堂知识点#1
标准数字格式字符串 https://docs.microsoft.com/zh-cn/dotnet/standard/base-types/standard-numeric-format-string ...