linux c语言 哲学家进餐---信号量PV方法一
1、实验原理
由Dijkstra提出并解决的哲学家进餐问题(The Dinning Philosophers Problem)是典型的同步问题。该问题是描述有五个哲学家共用一张圆桌,分别坐在周围的五张椅子上,在圆桌上有五个碗和五只筷子,他们的生活方式是交替地进行思考和进餐。平时,一个哲学家进行思考,饥饿时便试图取用其左右最靠近他的筷子,只有在他拿到两只筷子时才能进餐。进餐完毕,放下筷子继续思考。
2.实验内容:
显示出每个哲学家的工作状态,如吃饭,思考。连续运行30次以上都未出现死锁现象。
3.分析解决方案一:
现在引入问题的关键:这些哲学家很穷,只买得起五根筷子。他们坐成一圈,两个人的中间放一根筷子。哲学家吃饭的时候必须同时得到左手边和右手边的筷子。如果他身边的任何一位正在使用筷子,那他只有等着。所以我们就假设最多只有4民哲学家在进餐这样就能保证没有死锁的情况。
代码如下:
- 1 #include<unistd.h>
- 2 #define NUM 5
- 3 int ID[NUM]={0,1,2,3,4};
- 4 sem_t sem_chopsticks[NUM];
- 5 sem_t sem_eaters;
- 6 int eaters_num=0;//记录已经吃过饭的次数
- 7
- 8 //初始化信号量函数
- 9 void sem_signal_init(){
- 10 int i;
- 11 for(i=0;i<NUM;i++){
- 12 if(sem_init(&sem_chopsticks[i],0,1)==-1){
- 13 perror("oops:em_init error!");
- 14 exit(1);
- 15 }
- 16 }
- 17 if(sem_init(&sem_eaters,0,NUM-1)==-1){
- 18 perror("oops:em_init error!");
- 19 exit(1);
- 20 }
- 21
- 22
- 23 }
- 24
- 25
- 26
- 27 //执行函数,每个线程相当于一个哲学家 来进行
- 28 void * philosopher(void *ptid){
- 29 int pthread_id=*(int *)ptid%NUM;
- 30 printf("%d philosopher is thinking...\n",(int)pthread_id);
- 31 sem_wait(&sem_eaters);
- 32 //申请左筷子
- 33 sem_wait(&sem_chopsticks[pthread_id]);
- 34 printf("%d philosopher takes chopstick %d...\n",(int)pthread_id,(int)pthread_id);
- 35 //申请右筷子
- 36 sem_wait(&sem_chopsticks[(pthread_id+1)%NUM]);
- 37 printf("%d philosopher takes chopstick %d...\n",(int)pthread_id,((int)pthread_id+1)%NUM);
- 38 printf("%d philosopher is eating, %d philosopher had already dined.\n",(int)pthread_id,eaters_num);
- 39 sem_post(&sem_chopsticks[(pthread_id+1)%NUM]) ;
- 40 sem_post(&sem_chopsticks[pthread_id]);
- 41 sem_post(&sem_eaters);
- 42 eaters_num++;//吃过一次的人加加
- 43 printf("%d philosopher had dined, by now %d philosopher had already dined.\n",(int)pthread_id,eaters_num);
- 44
- 45 }
- 46
- 47
- 48
- 49
- 50 int main(int argc,char *argv[]){
- 51 int i,l,j,k;
- 52 //循环五个线程多少次
- 53 for(l=0;l<1;++l){
- 54 printf("*******%d times try *******",l+1);
- 55 pthread_t philosopher_threads[NUM];
- 56 sem_signal_init();
- 57 //循环创建五个线程并执行
- 58 for(i=0;i<NUM;i++){
- 59
- 60 printf("%d times\n",i);
- 61 if(pthread_create(&philosopher_threads[i],NULL,philosopher,&ID[i])!=0){
- 62 perror("oops:pthread_create error!");
- 63 exit(1);
- 64
- 65 }
- 66
- 67
- 68 }
- 69
- 70 //父线程等待子线程都结束才继续执行
- 71 for(j=0;j<NUM;j++){
- 72 pthread_join(philosopher_threads[j],NULL);
- 73 }
- 74 //结束销毁信号量
- 75 sem_destroy(&sem_eaters);
- 76 for(k=0;k<NUM;++k){
- 77 sem_destroy(&sem_chopsticks[k]);
- 78 }
- 79 eaters_num=0;
- 80 sleep(2);
- 81
- 82
- 83 }
- 84
- 85
- 86
- 87 return 0;
- 88 }
运行结果如下:
- 1 philosopher is thinking...
- 0 philosopher takes chopstick 0...
- 3 times
- 1 philosopher takes chopstick 1...
- 2 philosopher is thinking...
- 4 times
- 1 philosopher takes chopstick 2...
- 1 philosopher is eating, 0 philosopher had already dined.
- 3 philosopher is thinking...
- 4 philosopher is thinking...
- 1 philosopher had dined, by now 1 philosopher had already dined.
- 2 philosopher takes chopstick 2...
- 0 philosopher takes chopstick 1...
- 0 philosopher is eating, 1 philosopher had already dined.
- 4 philosopher takes chopstick 4...
- 3 philosopher takes chopstick 3...
- 0 philosopher had dined, by now 2 philosopher had already dined.
- 4 philosopher takes chopstick 0...
- 4 philosopher is eating, 2 philosopher had already dined.
- 4 philosopher had dined, by now 3 philosopher had already dined.
- 3 philosopher takes chopstick 4...
- 3 philosopher is eating, 3 philosopher had already dined.
- 3 philosopher had dined, by now 4 philosopher had already dined.
- 2 philosopher takes chopstick 3...
- 2 philosopher is eating, 4 philosopher had already dined.
- 2 philosopher had dined, by now 5 philosopher had already dined.
- --------------------------------
- Process exited after 2.127 seconds with return value 0
- 请按任意键继续. . .
后续方案将继续更新请关注!!!
linux c语言 哲学家进餐---信号量PV方法一的更多相关文章
- Linux下IPC中的信号量PV操作
代码如下所示,两边对照查看程序!(左图为先运行进程 右图为后运行进程) 运行的效果就是:当左边的进程检测到EOF,释放资源V操作之后,右边的进程会迅速的执行对应的printf的操作! 所有代码文 ...
- 利用Linux下的pthread_mutex_t类型来实现哲学家进餐问题
首先说一下什么是哲学家进餐问题,这是操作系统课程中一个经典的同步问题, 问题如下:如上图,有6个哲学家和6根筷子(那个蓝色部分表示哲学家,那个紫色长条部分表示筷子),他们分别被编了0~5的号!如果某个 ...
- Java哲学家进餐问题|多线程
Java实验三 多线程 哲学家进餐问题: 5个哲学家共用一张圆桌,分别坐在周围的5张椅子上, 在圆桌上有5个碗和5只筷子(注意是5只筷子,不是5双), 碗和筷子交替排列.他们的生活方式是交替地进行思考 ...
- 转载~kxcfzyk:Linux C语言多线程库Pthread中条件变量的的正确用法逐步详解
Linux C语言多线程库Pthread中条件变量的的正确用法逐步详解 多线程c语言linuxsemaphore条件变量 (本文的读者定位是了解Pthread常用多线程API和Pthread互斥锁 ...
- java笔记--超级类Object多线程的应用+哲学家进餐算法内部类与多线程结合
关于Object类中的线程方法: Object类是所有Java类的 父类,在该类中定义了三个与线程操作有关的方法,使得所有的Java类在创建之后就支持多线程 这三个方法是:notify(),notif ...
- Linux C语言操作MySQL
原文:Linux C语言操作MySQL 1.MySQL数据库简介 MySQL是一个开源码的小型关系数据库管理系统,体积小,速度快,总体成本低,开源.MySQL有以下特性: (1) 使用C和C++编写, ...
- linux c语言定时器
原文来自于:http://hi.baidu.com/opetrhsxszbckzd/item/126966cae5f9524aa9ba94f5 我只是把其重新排版标注一下. linux c语言定时器 ...
- Linux改变语言设置的命令
--Linux语言设置--------------2013/09/22Linux中语言的设置和本地化设置真是一个很繁琐的事情,时不时的会出现乱码的情况,在这篇文章中讨论的是shell中出现乱码的一些解 ...
- 第4章 同步控制 Synchronization ---哲学家进餐问题(The Dining Philosophers)
哲学家进餐问题是这样子的:好几位哲学家围绕着餐桌坐,每一位哲学家要么思考,要么等待,要么就吃饭.为了吃饭,哲学家必须拿起两支筷子(分放于左右两端).不幸的是,筷子的数量和哲学家相等,所以每支筷子必须由 ...
随机推荐
- css实现中间横线俩边文字效果
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 多测师讲解_肖sir _rf报错归纳(1):
错误一: 报错原因:文件格式 解决方案: 修改文件格式,将txt改成robot格式 错误二: rf 运行以后出现乱码现象 解决方案: 打开python的安装路径下:C:\python37\Lib\ ...
- 多测师讲解pthon_002字符,列表,元组,字段等
# # # 索引:# # # 正向索引: 0 1 2 3 4 5 6# # # l= a b c d e f g# # # 反向索引: -7 -6 -5 -4 ...
- MeteoInfoLab脚本示例:OMI Swath HDF数据
这个例子读取OMI卫星Swath数据中的CloudFaction变量并绘图.脚本程序: #Add data file folder = 'D:/Temp/hdf/' fns = 'OMI-Aura_L ...
- Jmeter请求之接口串联自动化测试(未完)
方案一:添加Cookie管理器,把用户的登录状态存在cookie管理器中,类似于浏览器 存储测试结果: 监听器->保存响应到文件,对结果进行存储 文件名前缀:保存到哪个地方前缀是什么D:\tes ...
- 【线段树】BZOJ 5334 数学计算
题目内容 小豆现在有一个数\(x\),初始值为\(1\).小豆有\(Q\)次操作,操作有两种类型: 1 m:\(x=x×m\),输出\(x\ mod\ M\): 2 pos:\(x=x/\)第\(po ...
- rabbitmq之后台管理和用户设置
前言 前面介绍了erlang环境的安装和rabbitmq环境安装,接下来介绍rabbitmq的web管理和用户设置. 启用后台管理插件 通过后台管理插件我们可以动态监控mq的流量,创建用户,队列等. ...
- centos8安装sersync为rsync实现实时同步
一,查看本地centos的版本: [root@localhost lib]# cat /etc/redhat-release CentOS Linux release 8.1.1911 (Core) ...
- xpath取末尾
from lxml import etree html = ''' <!DOCTYPE html> <html lang="en"> <head> ...
- Python之包的相关
包的产生: 由于模块不断更新,越写越大,仅用单个py文件会使模块逻辑不够清晰,所以需要将模块的不同功能放入不同的py文件,然后将所有py文件放在一个目录内,这个目录就是包 包就是一个包含用__init ...