IPC----哲学家就餐问题(并发与互斥)
哲学家就餐问题描述:
5个哲学家,5个筷子。5个哲学家围坐在一张桌子上,筷子放在分别放在每个哲学家的两旁。如果所有哲学家在某个时刻同时拿起左边的筷子,那么右边的筷子就都被其他的哲学家拿了,造成大家都无法吃饭。但是大家都不想放下左边的筷子(规则是先拿起左边筷子在拿起右边的,吃完饭在放下两个筷子),这就是死锁。
解决这个问题有个办法是
在拿起筷子前先判断左右两个筷子是否可用,可用才能拿,而且是同时拿,这样不相邻的哲学家就可以吃上饭,不会造成死锁。
实现代码如下
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h> union semun {
int val; /* Value for SETVAL */
struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */
unsigned short *array; /* Array for GETALL, SETALL */
struct seminfo *__buf; /* Buffer for IPC_INFO
(Linux-specific) */
}; //用于设置信号量所需要的联合体 int semid; int sem_del(int semid) //删除一个信号量集
{
int ret;
ret=semctl(semid,0,IPC_RMID,0); //不知道信号量集合中有几个信号量,故对第2个参数设为0
if (ret==-1)
printf("semdel falied\n");
return 0;
} void wait_for_2fork(int no)
{
int left =no; //左刀叉
int right = (no+1)%5; //右刀叉
struct sembuf buf[2] ={{left,-1,0},{right,-1,0}}; //-1表示为P操作 semop(semid,buf,2); //等待获取刀叉(资源)
} void free_2fork(int no)
{
int left =no; //左刀叉
int right = (no+1)%5; //右刀叉
struct sembuf buf[2] ={{left,1,0},{right,1,0}}; //-1表示为P操作 semop(semid,buf,2); //释放获取的刀叉(资源)
} void phliosophere(int no)
{
srand(getpid()); //以进程号作为随机数的种子
while(1)
{
printf("philosophere %d is thinking\n",no);
sleep(rand()%5+1);
printf("philosophere %d is hungry\n",no);
//sleep(rand()%5+1);
wait_for_2fork(no); //等待获取刀叉
printf("philosophere %d is eating\n",no);
sleep(rand()%5+1);
free_2fork(no); //释放刀叉
}
} int main()
{
//int semid;
semid=semget(IPC_PRIVATE,5,IPC_CREAT|0666); //创建5个私有信号量,每一个信号量相当于一把叉子
if(semid==-1)
{
printf("semget failed\n");
return 0;
} union semun su;
su.val=1;
int i;
for(i=0;i<5;i++)
semctl(semid,i,SETVAL,su); //初始化信号量 int no=0; //进程id
pid_t pid;
for(i=0;i<5;i++)
{
pid=fork();
if(pid==-1)
{
printf("fork failed\n");
return 0;
}
if(pid==0) //子进程
{
no=i;
break;
}
} phliosophere(no); //哲学家行为实现 return 0;
}
新问题描述:
设有5个哲学家,共享一张放有5把椅子的桌子,每人分得一把椅子,但是,桌子上共有5只筷子,在每人两边各放一只,哲学家们在肚子饥饿时才试图分两次从两边拿起筷子就餐。
条件:
1)拿到两只筷子时哲学家才开始吃饭。
2)如果筷子已在他人手上,则该哲学家必须等他人吃完之后才能拿到筷子。
3)任一哲学家在自己未拿到两只筷子前却不放下自己手中的筷子。
试:
1)描述一 个保证不会出现两个邻座同时要求吃饭的通信算法。
2)描述一个即没有两个邻座同时吃饭,有没有饿死(永远拿不到筷子)的算法
见参考2
参考:
用信号量解决哲学家就餐问题 http://www.oschina.net/code/snippet_724028_36857
操作系统并发和互斥:哲学家进餐问题 http://blog.sina.com.cn/s/blog_759803690101d9ne.html
哲学家就餐问题linux下c++代码 http://blog.sina.com.cn/s/blog_704553390100uq75.html
IPC----哲学家就餐问题(并发与互斥)的更多相关文章
- JAVA并发,经典死锁案例-哲学家就餐
转自:http://blog.csdn.net/tayanxunhua/article/details/38691005 死锁经典案例:哲学家就餐. 这个案例会导致死锁. 通过修改<Java编程 ...
- linux下多线程互斥量实现生产者--消费者问题和哲学家就餐问题
生产者消费者问题,又有界缓冲区问题.两个进程共享一个一个公共的固定大小的缓冲区.其中一个是生产者,将信息放入缓冲区,另一个是消费者,从缓冲区中取信息. 问题的关键在于缓冲区已满,而此时生产者还想往其中 ...
- 哲学家就餐问题-Java语言实现死锁避免
哲学家就餐问题-Java语言实现死锁避免 我死锁预防是至少破坏死锁产生的四个必要条件之一,带来的问题就是系统资源利用率低且不符合开发习惯,而死锁避免不是事先釆取某种限制措施破坏死锁的必要条件,只是注意 ...
- JAVA多线程学习--哲学家就餐问题
哲学家就餐问题是1965年由Dijkstra提出的一种线程同步的问题. 问题描述:一圆桌前坐着5位哲学家,两个人中间有一只筷子,桌子中央有面条.哲学家思考问题,当饿了的时候拿起左右两只筷子吃饭,必须拿 ...
- <<操作系统精髓与设计原理>>读书笔记(一) 并发性:互斥与同步(1)
<<操作系统精髓与设计原理>>读书笔记(一) 并发性:互斥与同步 并发问题是所有问题的基础,也是操作系统设计的基础.并发包括很多设计问题,其中有进程间通信,资源共享与竞争,多个 ...
- Linux环境下实现哲学家就餐问题
#include <stdio.h> #include <stdlib.h> #include <memory.h> #include <pthread.h& ...
- 并发编程---互斥锁---互斥锁与join的区别
互斥锁 互斥锁:就是把多个进程并发,修改成一块共享数据的操作变成串行,保证是一个一个来修改的. 缺点:效率低,加锁过程复杂 优点:增加了安全性 from multiprocessing import ...
- C++并发编程 互斥和同步
C++并发编程 异步任务(async) 线程基本的互斥和同步工具类, 主要包括: std::mutex 类 std::recursive_mutex 类 std::timed_mutex 类 std: ...
- JAVA并发同步互斥实现方式总结
大家都知道加锁是用来在并发情况防止同一个资源被多方抢占的有效手段,加锁其实就是同步互斥(或称独占)也行,即:同一时间不论有多少并发请求,只有一个能处理,其余要么排队等待,要么放弃执行.关于锁的实现网上 ...
随机推荐
- Python之路【番外篇】回顾&类的静态字段
回顾 回顾:字符串.列表.字典的修改关于内存的情况 一.字符串 str1 = 'luotianshuai' str2 = str1 print id(str1) print id(str2) prin ...
- swoole 教程
环境安装:http://blog.csdn.net/ldy3243942/article/details/40263735 Task使用以及swoole_client:http://blog.csdn ...
- Yii2 使用 Joins 查询
Join() JOIN_TYPE = INNER JOIN, LEFT OUTER JOIN, RIGHT OUTER JOIN, FULL OUTER JOIN 等等 语法 $query = new ...
- 多线程 GET
iOS中多线程的实现 方案 简介 语言 线程生命周期 使用频率 pthread 一套通用的多线程API 适用于 Unix / Linux / Windows 等系统 跨平台\可移植 使用难度大 C 程 ...
- echo '.SUFFIXES: .cpp' >> ${OUTPUT_FILE}
当前makefile或shell内支持文件后缀的类型列表,意思是文件支持.cpp结尾的类型,并且将他,输出到OUTPUT_FILE函数. 见网上有人说: “makefile中 .SUFFIXES: . ...
- Spring Quartz定时调度任务配置
applicationContext-quartz.xml定时调度任务启动代码: <?xml version="1.0" encoding="UTF-8" ...
- 高效率http页面优化法则一【JS对DOM的操作】
高效http页面优化法则一很多人都认为JS的效率太慢了,都不愿意用js来实现相对困难一点的程序逻辑.在这里我要说的是其实js的效率并不慢,慢的是DOM,如果操作好DOM,你的js效率将提高接近千倍(这 ...
- android 读取SQLite android could not open the database in read/write mode错误
由于AndroidManifest.xml文件中uses-permission没有设置权限问题 <uses-permission android:name="android.permi ...
- Java并发包源码学习之AQS框架(二)CLH lock queue和自旋锁
上一篇文章提到AQS是基于CLH lock queue,那么什么是CLH lock queue,说复杂很复杂说简单也简单, 所谓大道至简: CLH lock queue其实就是一个FIFO的队列,队列 ...
- DateEdit和TimeEdit用法
DateEdit 控件默认情况下,显示的只有日期,没有时间.下面介绍2中日期和时间同时显示的方法: 1.Properties.VistaDisplayMode 为true, 2.Properties. ...