哲学家就餐问题

  • 背景:
  1. 假设5位哲学家住在一起(可以推广到n),每天生活就是思考和吃饭,每位哲学家需要2把叉子来吃意大利面.
  2. 就餐安排: 一张圆桌,5个板凳,5个盘子,5把叉子,每个想吃饭的哲学家做到椅子上,使用盘子2侧的叉子来吃面条,
  3. 问题: 设计算法 保证互斥(2位哲学家不能使用相邻的叉子),同时还要避免死锁(每个哲学家都在等待叉子,且占用了叉子)和饥饿

信号量解决方案

  • 规定: 每位哲学家首先拿起左边的叉子,然后拿起右边的叉子
semaphore fork[5] = {1};
int i;
void philosopher (int i) {while (true) {think();wait(fork[i]); //等待左边的叉子wait(fork[(i+1) % 5]; // 等待右边的叉子eat();signal(fork[(i+1) % 5]); // 放回右边的叉子signal(fork[i]; //放回左边的叉子 (增加信号量)}
}
void mian() {parbegin(philosopher(0),philosopher(1).....philosopher(4));
}
  • 此方案会导致死锁: 所有哲学家同时坐下来,都拿起左边的叉子,都去伸手拿右边的叉子,却都没有拿到

对上面死锁危险的解决方案:
  1. 再增加5把叉子,
  2. 哲学家学会只使用一把叉子吃面
  3. 增加服务员: 限制每次最多只能4个哲学家坐下来,那么至少有一个哲学家能够拿到2把叉子

增加服务员方案

  • 一个信号量room表示 : 限制每次哲学家同时坐下的数量
semaphore fork[5] = {1};
semaphore room = 4;
int i;
void philosopher (int i) {while (true) {think();wait(room);wait(fork[i]);wait(fork[(i+1) % 5]);eat();signal(fork[(i+1) % 5]);signal(fork[i]);signal(room);}
}
void main() {parbegin(philosopher(0),philosopher(1).....philosopher(4));
}

基于管程的解决方案

  1. 定义 5个管程的条件变量, 每把叉子对应一个条件变量,用来标识哲学家 等待 的叉子可用情况,

  2. 开一个bool数组记录每把叉子是否可用(true/false)

  3. 管程包含2个过程

    1. get_forks : 表示取哲学家左右的叉子, 如果至少有1把不可以用,那么在条件变量队列中等待,使得其他哲学家进程进入管程
    2. release_forks : 标识2把叉子可用
  4. 信号量方案类似,都是首先拿起左边的叉子,然后拿起右边的叉子

monitor dining_controller; // 声明管程
cron ForkReady[5];  //  管程的条件变量
bool fork[5] = {true}; // 标记叉子是否可用void get_forks(int pid) { // pid既代表哲学家又代表叉子int left = pid;int right = (pid + 1) % 5;if (!fork[left]) // 左边叉子被使用,则等待条件变量cwait(ForkReady[left]);fork[left] = false;//左边叉子现在可以归我们用了,再次标记为不能用if (!fork[right])cwait(ForkReady[right]);fork[right] = false;
}void release_forks(int pid) {int left = pid;int right= (pid + 1) % 5;if (empty(ForkReady[left])) // 没有哲学家在该队列上等待,则该叉子可以使用fork[left] = true;else //如果还有等待,增加信号量csignal(ForkReady[left]);/* 释放右边的叉子 */if (empty(ForkReady[right]))fork[right] = true;elsecsignal(ForkReady[right]);
}void philosopher(int i) {while (true) {think();get_forks(i);eat();release_forks(i);}
}
void main() {parbegin(philosopher(0),philosopher(1).....philosopher(4));
}

死锁和饥饿-哲学家就餐问题相关推荐

  1. Thinking in Java---从哲学家就餐问题看死锁现象

    我们知道一个对象可以有synchronized方法或其他形式的加锁机制来防止别的线程在互斥还没释放的时候就访问这个对象.而且我们知道线程是会变成阻塞状态的(挂起),所以有时候就会发生死锁的情况:某个任 ...

  2. 哲学家就餐与死锁问题,死锁产生的条件以及解决方案

    请结合经典案例-哲学家就餐,来谈谈你对死锁的理解,以及怎么预防和解除死锁? 哲学家就餐 描述:在一张圆桌上,有n个哲学家,n支筷子,他们的生活方式只是交替地进行思考和进餐,饥饿时便试图取其左.右最靠近 ...

  3. Java多线程学习四十二:有哪些解决死锁问题的策略和哲学家就餐问题

    线上发生死锁应该怎么办 如果线上环境发生了死锁,那么其实不良后果就已经造成了,修复死锁的最好时机在于"防患于未然",而不是事后补救.就好比发生火灾时,一旦着了大火,想要不造成损失去 ...

  4. 哲学家就餐问题python_哲学家就餐问题与死锁

    问题描述 哲学家就餐问题(Dining philosophers problem)是在计算机科学中的一个经典问题,用来演示在并发计算中多线程同步(Synchronization)时产生的问题. 哲学家 ...

  5. 哲学家就餐问题--信号量和互斥量预防死锁

    哲学家就餐问题可以采取预防死锁的方案,就是使用互斥量和信号量锁定资源. 互斥量: 对资源进行锁定的意思就是说,当一个哲学家使用叉子的时候,他首先要先把叉子锁定,然后,拿起来.这个时候如果别的哲学家也来 ...

  6. 哲学家就餐(避免死锁)(多进程版)

    哲学家就餐(避免死锁)(多进程版) 哲学家就餐利用信号量在多进程之间实现 下面展示一些代码片段 #include <stdio.h> #include <unistd.h> # ...

  7. 哲学家就餐问题(如何避免死锁)(多线程版)

    哲学家就餐问题 多线程编程中,常常会遇到线程间访问共享资源的问题,如果处理不当则会发生死锁,某一个线程可能永远访问不到共享资源. 为了避免死锁的发生,提出哲学家就餐问题. 下面展示一些代码片段 #in ...

  8. 哲学家就餐问题的三种避免死锁的解法(PV操作)

    哲学家就餐问题的三种避免死锁的解法(PV操作) 方案一:最多允许有四位哲学家同时去拿左边的筷子,然后再拿右边的筷子,最终保证至少有一位哲学家能够进餐,并在就餐完毕时同时释放他用过的两只筷子,从而使更多 ...

  9. 多线程“死锁”之“哲学家就餐”代码实现

    死锁:就是两个或者两个以上的线程相互占用对方的需要的资源,而不进行释放,导致彼此都在等待对方释放资源,产生了无限制的等待的现象. "哲学家就餐"的问题不在赘述,可以自行百度或者Go ...

最新文章

  1. BN和Dropout在训练和测试时有哪些差别?
  2. 【动态规划】背包模型
  3. 利用jsoncpp将json字符串转换为Vector
  4. mysql 取绝对值_自学MySQL第六天
  5. Ubuntu安装教程【超多图】
  6. 面对一夜狼人杀特殊的游戏机制,取得胜利很难吗?还可以
  7. 前端面试系列-JS 异步编程
  8. abp框架java,【Net】ABP框架学习之正面硬钢
  9. 淘宝「改名自由」后,上百万人连夜告别了前任……
  10. Vs2012调试本地windows服务
  11. PyTorch 深度学习:38分钟快速入门——RNN 做图像分类
  12. java 甘特图_[Java教程]JQuery.Gantt(甘特图)开发
  13. AtCoder题解——Beginner Contest 168——E - ∙ (Bullet)
  14. 监控摄像头服务器中断是什么原因,监控系统常见问题故障及处理方法
  15. 工业智能网关BL110应用之四十三:网口采集欧姆龙PLC的配置
  16. 点云统一法线方向(未知视点)
  17. 大数据在高校的应用场景_大数据技术在高校教育中的应用
  18. 大数据概论、大数据概念、大数据特点(4V)、Volume(大量)、Velocity(高速)、Variety(多样)、Value(低价值密度)、大数据应用场景、大数据发展前景、大数据部门间业务流程分析
  19. vue3实现鼠标左键拖拽画矩形框框选功能
  20. 继续安利两个漫画App

热门文章

  1. 天津大学计算机网络专业排名,2019计算机考研天津大学先进网络技术与应用重点实验室简介...
  2. 2021软件测试面试题汇总【备战金九银十】内容较长建议收藏
  3. UsbAccessory和UsbDevice的区别
  4. NTLDR是做什么的,丢失了如何恢复
  5. <2>重定向的用法说明和举例
  6. 多源数据的融合发展现状与趋势(二)——全色、多光谱、高光谱图像融合
  7. UVA 707 - Robbery
  8. Debian搭建DBMS(MariaDB)
  9. ChinaSkills技能大赛网络系统管理Debian模块(样题一)||初始化环境之登录欢迎语
  10. 计算机视觉领域稍微容易中的期刊系列(二)1