哲学家就餐问题描述:

  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----哲学家就餐问题(并发与互斥)的更多相关文章

  1. JAVA并发,经典死锁案例-哲学家就餐

    转自:http://blog.csdn.net/tayanxunhua/article/details/38691005 死锁经典案例:哲学家就餐. 这个案例会导致死锁. 通过修改<Java编程 ...

  2. linux下多线程互斥量实现生产者--消费者问题和哲学家就餐问题

    生产者消费者问题,又有界缓冲区问题.两个进程共享一个一个公共的固定大小的缓冲区.其中一个是生产者,将信息放入缓冲区,另一个是消费者,从缓冲区中取信息. 问题的关键在于缓冲区已满,而此时生产者还想往其中 ...

  3. 哲学家就餐问题-Java语言实现死锁避免

    哲学家就餐问题-Java语言实现死锁避免 我死锁预防是至少破坏死锁产生的四个必要条件之一,带来的问题就是系统资源利用率低且不符合开发习惯,而死锁避免不是事先釆取某种限制措施破坏死锁的必要条件,只是注意 ...

  4. JAVA多线程学习--哲学家就餐问题

    哲学家就餐问题是1965年由Dijkstra提出的一种线程同步的问题. 问题描述:一圆桌前坐着5位哲学家,两个人中间有一只筷子,桌子中央有面条.哲学家思考问题,当饿了的时候拿起左右两只筷子吃饭,必须拿 ...

  5. <<操作系统精髓与设计原理>>读书笔记(一) 并发性:互斥与同步(1)

    <<操作系统精髓与设计原理>>读书笔记(一) 并发性:互斥与同步 并发问题是所有问题的基础,也是操作系统设计的基础.并发包括很多设计问题,其中有进程间通信,资源共享与竞争,多个 ...

  6. Linux环境下实现哲学家就餐问题

    #include <stdio.h> #include <stdlib.h> #include <memory.h> #include <pthread.h& ...

  7. 并发编程---互斥锁---互斥锁与join的区别

    互斥锁 互斥锁:就是把多个进程并发,修改成一块共享数据的操作变成串行,保证是一个一个来修改的. 缺点:效率低,加锁过程复杂 优点:增加了安全性 from multiprocessing import ...

  8. C++并发编程 互斥和同步

    C++并发编程 异步任务(async) 线程基本的互斥和同步工具类, 主要包括: std::mutex 类 std::recursive_mutex 类 std::timed_mutex 类 std: ...

  9. JAVA并发同步互斥实现方式总结

    大家都知道加锁是用来在并发情况防止同一个资源被多方抢占的有效手段,加锁其实就是同步互斥(或称独占)也行,即:同一时间不论有多少并发请求,只有一个能处理,其余要么排队等待,要么放弃执行.关于锁的实现网上 ...

随机推荐

  1. Xunsearch 中文全文搜索

    原文地址:http://www.yiichina.com/code/661 官网地址:http://www.xunsearch.com/ 1.安装 wget http://www.xunsearch. ...

  2. phpStudy 创建多个站点,绑定域名

    默认情况下,phpStudy 的站点根目录是在它自己的WWW目录,比如 F:\phpStudy\WWW,访问的地址可以是 http://127.0.0.1/   或 http://localhost/ ...

  3. XMLHttpRequestUtil

    //XMLHttpRequest类 function XMLHTTPRequestUtil() { this.Instance = null; this.GetXMLHttpRequest = fun ...

  4. 关于帧中继和ppp的补充笔记

    帧中继: · 两个设备都要启用 帧中继功能, 否则是不能 ping通的 · 两个设备上的接口serial要 no shutdown · · 一定要配置dlci地址(号). 否则就不能起来pvc 可以 ...

  5. 再读<<基于MVC的JavaScript Web 富应用开发>>

    工作的时候粗读过这本书的几章内容,真真是囫囵吞枣~~目前手边就剩这一本,重新读才觉得先前是没看明白啊!这个作者博闻强识,对这些插件.库了解的非常多.记录下,查的资料 订阅/发布 jQuery Tiny ...

  6. wtforms 使用

    wtforms是一个表单模板库, 下面以修改密码表单为例简单说明其用法. 我们可以用python代码定义form的基本元素, 比如用户名/邮箱, 并给定各个元素的validation条件. 然后在re ...

  7. resin

    http://blog.csdn.net/sea0x/article/details/6097531 resin 启动: resin 配置文件摘取: <server-default> &l ...

  8. findByExample(Object exampleEntity)方法得到的List判断是否为空,不可用(lis != null)

    用findByExample(Object exampleEntity)方法可以应用在用户登录上面,获得有登陆名和密码的user对象进行查询. 返回两者都符合的对象列表,为空则登陆失败. 错误的方法: ...

  9. Hibernate面试题

    一.谈一谈Hibernate的缓存机制 1.一级缓存: 内部缓存存在于HIbernate中又叫一级缓存,他属于应用事务级缓存. 2.二级缓存: 01.应用级缓存. 02.分布式缓存. 条件:数据不会被 ...

  10. jquery mobile cannot be created in a document with origin 'null' and URL

    jquery mobile cannot be created in a document with origin 'null' and URL http://zhidao.baidu.com/lin ...