哲学家就餐问题 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.循环等待 虽然 ...
随机推荐
- 细说可空类型 nullable PropertyType
可空类型是System.Nullable结构体的实列.一个可空类型代表了相应值类型的正确范围附加null值.这么说来,其实也不是很明子,命题嘛,一般不求易懂,但求准确. 那我就来说说这可空类型吧,上次 ...
- 为什么每次登录要手动 source /etc/profile ...
由于执行顺序如下,故追个查看以下文件,看看是不是 JAVA_HOME, PATH 等环境变量在后面的文件中被重写覆盖了. 1. /etc/profile2. /etc/environment3. ~/ ...
- 如何配置docker仓库
创建文件 /etc/docker/daemon.json,写入国内镜像URL地址 { "registry-mirrors": [ "https://rq5uyt7.mir ...
- selenium + python 环境配置 (一)
超级无敌菜鸟 终于有空学习一下python 和 selenium 啦 第一步: 环境配置 (Windows版) 1. 下载安装python 根据你的电脑,下载一个python吧 这儿装的是pyt ...
- Java面试 - 在Java中, 既然构造方法是一个方法,那么为什么不使用void 定义呢?
Java程序编译器是根据代码结构来进行编译处理的,执行的时候也是根据代码结构来处理的. 如果在构造方法上使用void,那么此结构就会与普通方法的结构相同,这样编译器会认为此方法是一个 普通方法,而普通 ...
- Oracle 计算时间格式平均值
select to_char((to_date('2019-07-01', 'yyyy-mm-dd') + numtodsinterval(avg(begin_time_second), 'secon ...
- 给出一个javascript的Helloworld例子
1.基础知识:Helloworld:例 1.1<html><head> <!-- 如果你用notepad建立一个txt之后你再改为html,一定在存时,要存成ut ...
- Counting Cliques(HDU-5952)【DFS】
题目链接:https://vjudge.net/problem/HDU-5952 题意:有一张无向图,求结点数量为S的团的数量. 思路:如果不加一点处理直接用DFS必然会超时,因为在搜索过程中会出现遍 ...
- scrapy 爬取纵横网实战
前言 闲来无事就要练练代码,不知道最近爬取什么网站好,就拿纵横网爬取我最喜欢的雪中悍刀行练手吧 准备 python3 scrapy 项目创建: cmd命令行切换到工作目录创建scrapy项目 两条命 ...
- 安装jar包到本地仓库
1.控制台安装 安装指定文件到本地仓库命令:mvn install:install-file-DgroupId=<groupId> : 设置项目代码的包名(一般用组织名)-Da ...