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方法一的更多相关文章

  1. Linux下IPC中的信号量PV操作

    代码如下所示,两边对照查看程序!(左图为先运行进程 右图为后运行进程)    运行的效果就是:当左边的进程检测到EOF,释放资源V操作之后,右边的进程会迅速的执行对应的printf的操作! 所有代码文 ...

  2. 利用Linux下的pthread_mutex_t类型来实现哲学家进餐问题

    首先说一下什么是哲学家进餐问题,这是操作系统课程中一个经典的同步问题, 问题如下:如上图,有6个哲学家和6根筷子(那个蓝色部分表示哲学家,那个紫色长条部分表示筷子),他们分别被编了0~5的号!如果某个 ...

  3. Java哲学家进餐问题|多线程

    Java实验三 多线程 哲学家进餐问题: 5个哲学家共用一张圆桌,分别坐在周围的5张椅子上, 在圆桌上有5个碗和5只筷子(注意是5只筷子,不是5双), 碗和筷子交替排列.他们的生活方式是交替地进行思考 ...

  4. 转载~kxcfzyk:Linux C语言多线程库Pthread中条件变量的的正确用法逐步详解

    Linux C语言多线程库Pthread中条件变量的的正确用法逐步详解   多线程c语言linuxsemaphore条件变量 (本文的读者定位是了解Pthread常用多线程API和Pthread互斥锁 ...

  5. java笔记--超级类Object多线程的应用+哲学家进餐算法内部类与多线程结合

    关于Object类中的线程方法: Object类是所有Java类的 父类,在该类中定义了三个与线程操作有关的方法,使得所有的Java类在创建之后就支持多线程 这三个方法是:notify(),notif ...

  6. Linux C语言操作MySQL

    原文:Linux C语言操作MySQL 1.MySQL数据库简介 MySQL是一个开源码的小型关系数据库管理系统,体积小,速度快,总体成本低,开源.MySQL有以下特性: (1) 使用C和C++编写, ...

  7. linux c语言定时器

    原文来自于:http://hi.baidu.com/opetrhsxszbckzd/item/126966cae5f9524aa9ba94f5 我只是把其重新排版标注一下. linux c语言定时器 ...

  8. Linux改变语言设置的命令

    --Linux语言设置--------------2013/09/22Linux中语言的设置和本地化设置真是一个很繁琐的事情,时不时的会出现乱码的情况,在这篇文章中讨论的是shell中出现乱码的一些解 ...

  9. 第4章 同步控制 Synchronization ---哲学家进餐问题(The Dining Philosophers)

    哲学家进餐问题是这样子的:好几位哲学家围绕着餐桌坐,每一位哲学家要么思考,要么等待,要么就吃饭.为了吃饭,哲学家必须拿起两支筷子(分放于左右两端).不幸的是,筷子的数量和哲学家相等,所以每支筷子必须由 ...

随机推荐

  1. 持续集成工具之Jenkins使用配置

    在上一篇博客中,我们主要介绍了DevOps理念以及java环境和jenkins的安装,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/13805666.html: ...

  2. 多测师讲解python _unttest框架001(基本格式)_高级讲师肖sir

    1.unittest基本介绍 import unittest #导入unittest模块 #class Test(unittest.TestCase): def setUp(self): #创建dri ...

  3. java 画 哆啦A梦

    package Demo;import javax.imageio.ImageIO;import java.awt.*;import java.awt.image.BufferedImage;impo ...

  4. 学习ing

    1.从硬件和逻辑两个角度探讨什么是内存?硬件上看,内存就是电脑上的硬件--内存条.内存通过内存条不同的实现原谅分为DRAM(DRAM已经发展出好多代)和SRAM.从逻辑的角度来说,内存就是一个可以随机 ...

  5. docker设置http访问

    1 编辑配置文件    vim /etc/docker/daemon.json { "registry-mirrors": ["https://a4fyjv0u.mirr ...

  6. Cypress系列(68)- request() 命令详解

    如果想从头学起Cypress,可以看下面的系列文章哦 https://www.cnblogs.com/poloyy/category/1768839.html 作用 发起一个 HTTP 请求 语法格式 ...

  7. 【应用服务 App Service】发布到Azure上的应用显示时间不是本地时间的问题,修改应用服务的默认时区

    问题情形 应用程序发布到App Service后,时间显示不是北京时间,默认情况为UTC时间,比中国时间晚 8 个小时. 详细日志 无 问题原因 Azure 上所有的服务时间都采用了 UTC 时间. ...

  8. Java8中Stream 的一些用法

    数据结构和数据准备 @Data @AllArgsConstructor @NoArgsConstructor static class StreamItem { Integer id; String ...

  9. Synergy屏幕共享键鼠 (for Mac&Ubuntu)

    Synergy屏幕共享键鼠(for Mac&Ubuntu) 1.   简介 一套键盘和鼠标,操控多台电脑,下面介绍下Mac和Ubuntu之间的共享.(synergy分为服务端和客户端,把插着鼠 ...

  10. 更换Centos的yum源

    1.备份 mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup 2.下载新的CentOS-Base ...