哲学家就相当于线程,叉子就相当于资源。每个线程需要获取特定的两个资源才可以执行“吃”操作。每个叉子只能被特定的两个线程访问,且访问叉子时是互斥的。假设数据结构设计一个信号量数组,5个元素代表5个叉子,每个信号量的初始值(最大值)为1 代表每个叉子只能被1个线程同时访问 ,即互斥。0号线程只能访问0号资源和1号资源,1号线程只能访问1号资源和2号资源......4号线程只能访问4号资源和0号资源。

那么有人这么设计,每个哲学家先拿右边的叉子,再拿左手边的叉子。如果无法同时拿起两个叉子就释放掉自己占用的资源。

这个算法有一定的缺陷,如果线程/进程的时间片大小和 takefork(i) 执行的时间一致,那么当CPU执行完“先拿右边的叉子”后时间片用完,切换到下一个就绪线程执行“先拿右边的叉子”...到最后所有线程都拿起了右边的叉子,无法拿起左边的叉子,最后有可能再一同释放,不断循环....

如果再此基础上添加一个条件,如果我要尝试拿叉子的时候把左右两个叉子一起锁住呢?如果锁不住就释放锁。即要么两个一起拿,要么就不拿叉子进入等待。

怎么实现呢,先理一理规则。

当自己需要进食的时候,需要判断左边的叉子和右边叉子的状态是否可用。如果可用则消耗掉这两把叉子资源,不可用则进行等待。所以,需要一个叉子的状态数组状态分为可用和不可用,由于数组本身的访问不具有互斥性,所以还需要一个互斥量来保护状态数组的访问;

#define  N     5
#define  LEFT  i
#define  RIGHT (i+1)%N
#define  FREE  0
#defind  USED  1
int   state[N];      //记录每个叉子的状态,初始值为FREE
semaphore mutex    ;      //保护state[]的互斥访问,初始值为1void philosopher(int i )  //第i个哲学家需要拿第i号和(i+1)%N号的叉子
{bool  couldeat = false;while(!couldeat){P(mutex);          //访问state前需要Pif(state[LEFT] == FREE && state[RIGHT ] == FREE){state[LEFT  ] = USED ;state[RIGHT ] = USED ;V(mutex);       //访问state完才可以释放couldeat = true;}else{V(mutex);....hunger(i);        // 哲学家自身进入饥饿(阻塞)状态}}....eat()......             //获取到两把叉子就可以执行自己的私有操作了P(mutex);          //访问state前需要Pstate[LEFT  ] = FREE ;state[RIGHT ] = FREE ;//如果左边的左边叉子可用,那么通知左边的哲学家可以就餐if( state[(LEFT - 1)%N] ==FREE){notice(LEFT);}//如果右边的右边叉子可用,那么通知右边的哲学家可以就餐if( state[(RIGHT + 1)%N] ==FREE){notice(RIGHT );}V(mutex);
}

上述代码是一叉子为资源的一个伪码。如果以哲学家为资源的呢代码该如何呢?思路是一样的,用一个状态数组表示哲学家的3种状态,思考、饥饿、就餐。其中,隔壁的哲学家在就餐意味着自己无法就餐,进入阻塞态。隔壁没有哲学家就餐才意味着自己身边的两个叉子可用。

其中用一个函数判断i号哲学家满不满足吃饭资格的函数:

void  test_take_left_right_forks(int i){if(state[i] == HUNGRY && state[LEFT] != EATING && state[RIGHT] != EATING){//当隔壁的哲学家不在吃饭且自己处于饥饿时唤醒第i号哲学家就餐state[i] == EATING;V(s[i]);}}

代码框架如下图,主要需要实现的是take_forks(i);和 put_forks(i).   ,think() 和 eat()是自己的私有操作。

void take_forks(int i ) { // i号哲学家试图拿叉子P(mutex);state[i] = HUNGRY;   //让自己为饥饿状态test_take_left_right_forks(i);   //如果没叉子那么s[i]==0,有叉子则s[i] ==1V(mutex);P(s[i]);             //没有叉子则阻塞自身
}void put_forks(int i ) { // i号哲学家吃完并通知隔壁的哲学家P(mutex);state[i] = THINKING;                 //自己不处于吃饭状态啦!!!test_take_left_right_forks(LEFT);    //因为自己吃饭导致隔壁哲学家饥饿(阻塞),所以要尝试唤醒他test_take_left_right_forks(RIGHT);   //右边也一样V(mutex);}

操作系统原理:哲学家就餐经典问题相关推荐

  1. 【操作系统】哲学家就餐问题

    问题 有五个哲学家围坐在一圆桌旁,桌中央有一盘通心粉,每人面前有一只空盘子,每两人之间放一只筷子.每个哲学家的行为是思考,感到饥饿,然后吃通心粉.为了吃通心粉,每个哲学家必须拿到两只筷子,并且每个人只 ...

  2. 【操作系统/OS笔记14】经典同步问题:读者-写者问题、哲学家就餐问题

    本次笔记内容: 10.6 经典同步问题-1 10.7 经典同步问题-2 10.8 经典同步问题-3 10.9 经典同步问题-4 10.10 经典同步问题-5 10.11 经典同步问题-6 文章目录 读 ...

  3. 操作系统 | PV操作七大经典问题 生产者消费者 读者写者 哲学家进餐 理发师理发睡觉 和尚打水 吸烟者 吃水果

    一.生产者消费者问题 生产者消费者问题(英语:Producer-consumer problem),也称有限缓冲问题(英语:Bounded-buffer problem),是一个多线程同步问题的经典案 ...

  4. 操作系统(四) | 经典进程的同步问题(生产者--消费者问题、哲学家进餐问题、读者--写者问题)

    文章目录 生产者--消费者问题 分析 实现 哲学家进餐问题 方法一:最多4人同时拿左筷子,最终保证一人能进餐 方法二:同时给左右筷子 解法1:AND信号量 解法2:信号量保护机制 方法三:让奇数先左后 ...

  5. 全国计算机四级——操作系统原理笔记

    学习建议:结合书和笔记把知识过一遍 -> 买题库刷试卷 -> 始终学不明白的题目去刷章节题目 -> 背新增试卷题目 关于本笔记:写者参加2022年5月的考试,参考<全国计算机等 ...

  6. 操作系统原理总结,非科班必看!!!

    操作系统原理总结 一.操作系统概述 1.操作系统概念 2.操作系统的基本功能 二.处理机管理 1.作业的概念 2.作业的过程 3.单道批处理系统的作业调度算法 4.进程的概念 5.进程和程序的区别和联 ...

  7. 计算机网络 本 课程导学,课程导学 - 操作系统原理 - 浙江大学网络教育精品资源共享课...

    课程名称:操作系统原理授课时数:32学时 面向对象:计算机科学与技术专业 预修课程要求:C/C++程序设计语言.数据结构 一.课程介绍 操作系统是一门理论与实践并重的专业核心课程.本课程的主要任务是帮 ...

  8. 【操作系统原理要点笔记 附带英文词汇】

    Command-Line(CLI),GraphicsUserInterface(GUI),Batch命令行(CLI).图形用户界面(GUI).批处理 manipulation操纵 facilities ...

  9. 哲学家就餐 linux实现_Linux哲学的9个主要原则如何影响您

    哲学家就餐 linux实现 上一次,我在Linux哲学的影响中讨论了Linux哲学的较高层次的观点. 关于它有一些非常好的讨论,许多博客联合了Opensource.com. 我从上一篇文章中收到的评论 ...

最新文章

  1. jQuery学习笔记之extend方法小结
  2. LaTeX:公式及编号
  3. internal server error怎么解决_MAC中MySQL添加my.cnf和PID file解决方案
  4. C# 关于MVC框架的简单实例(计算器)
  5. bat(续六)-windows批处理set命令
  6. 【Siddhi】Siddhi 如何表示布尔 Syntax error in SiddhiQL, mismatched input ‘boolean
  7. Golang 删除切片指定元素
  8. C#中将字符串中某字符不区分大小写并按全字匹配替换为空
  9. DGIOT物联网开源平台——腾讯云轻量应用服务器部署
  10. 微信小程序view居中问题
  11. GPS 经纬度转换 百度、高德经纬度
  12. android分享微信获取资源失败怎么办,Android处理使用Intent分享图片,以及在微信7.0版本出现“获取资源失败,无法分享到朋友圈”,导致分享失败的问题...
  13. NGUI-动画Tween
  14. mysql 手工配置_小姜学网络(MySQL数据库的手工安装与配置)附代码
  15. ppt文件太大如何压缩变小?
  16. 如何使用Mezzanine
  17. Qt中文乱码原因及解决方案
  18. unordered_set使用介绍
  19. 入网许可证_入网许可证
  20. 大数据需要学习哪些技术?

热门文章

  1. 一步一步oa办公系统java,OA项目 一个OA办公系统的java源码 联合开发网 - pudn.com
  2. A股十大股东持股数据查询网站的数据库设计
  3. 车载网络技术详解 —— 车载网络系统基础(✨您绝不可错过的呕心力作✨)
  4. javascript之雪花特效
  5. 【操作系统基础】文件管理系统(一)
  6. stm32 关于GPIO寄存器操作
  7. 【科研技巧】Mac下使用SciDavis绘制科研论文图教程(安装及使用)
  8. response是什么意思中文_response是什么意思
  9. HTTP的常用方法、GET和POST的区别
  10. 数据库概论——物理独立性和逻辑独立性