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并发同步互斥实现方式总结
大家都知道加锁是用来在并发情况防止同一个资源被多方抢占的有效手段,加锁其实就是同步互斥(或称独占)也行,即:同一时间不论有多少并发请求,只有一个能处理,其余要么排队等待,要么放弃执行.关于锁的实现网上 ...
随机推荐
- "Java 反序列化"过程远程命令执行漏洞
一.漏洞描述 国外 FoxGlove 安全研究团队于2015年11月06日在其博客上公开了一篇关于常见 Java 应用如何利用反序列化操作进行远程命令执行的文章.原博文所提到的 Java 应用都使 ...
- C# 表达式树demo
class Program { static void Main(string[] args) { //创建Expression参数 var left = System.Linq.Expression ...
- jQuery 学习之路(1):引子
一.主流 javascript 库 除 jQuery 外,还有 Prototype.Dojo.YUI.ExtJS.MooTools ,其中 Prototype 较老,结构设计较为松散,ExtJS 界面 ...
- grep之字符串搜索算法Boyer-Moore由浅入深(比KMP快3-5倍)
这篇长文历时近两天终于完成了,前两天帮网站翻译一篇文章“为什么GNU grep如此之快?”,里面提及到grep速度快的一个重要原因是使用了Boyer-Moore算法作为字符串搜索算法,兴趣之下就想了解 ...
- javascript客户端检测技术
1. Firefox Gecko是firefox的呈现引擎.当初的Gecko是作为通用Mozilla浏览器一部分开发的,而第一个采用Gecko引擎的浏览器是Netscape6: 我们可以使用用户代理 ...
- Python-时间操作
目录 Python标准模块 datetime 数据类型 datetime timedelta 字符串和datetime的相互转换 datetime 转 字符串 str strftime strftim ...
- [译]AngularJS中几种Providers(Factory, Service, Provider)的区别
原文: http://blog.xebia.com/2013/09/01/differences-between-providers-in-angularjs/ 什么是Provider? Angula ...
- 【AngularJS】—— 4 表达式
前面了解了AngularJS的基本用法,这里就跟着PDF一起学习下表达式的相关内容. 在AngularJS中的表达式,与js中并不完全相同. 首先它的表达式要放在{{}}才能使用,其次相对于javas ...
- Nginx安装配置(转)
Nginx 安装配置 Nginx("engine x")是一款是由俄罗斯的程序设计师Igor Sysoev所开发高性能的 Web和 反向代理 服务器,也是一个 IMAP/POP3/ ...
- hdu1026.Ignatius and the Princess I(bfs + 优先队列)
Ignatius and the Princess I Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (J ...