文章目录

  • 一、设计目的
  • 二、设计内容
  • 三、开发环境
  • 四、分析设计
    • 【1】实验原理
    • 【2】数据及程序结构
  • 五、运行示例及结果分析
  • 六、总结

一、设计目的

死锁是进程并发执行过程中可能出现的现象,所谓死锁,是指多个进程在运行过程中因争夺资源而造成的一种僵局。哲学家就餐问题是描述死锁的经典例子。为了防止死锁,可以采用资源预分配法或者资源按序分配法。资源预分配法是指进程在运行前一次性地向系统申请它所需要的全部资源,如果系统当前不能够满足进程的全部资源请求,则不分配资源, 此进程暂不投入运行,如果系统当前能够满足进程的全部资源请求, 则一次性地将所申请的资源全部分配给申请进程。

二、设计内容

哲学家进餐问题的模拟。

三、开发环境

windows环境,Myeclipse平台。

四、分析设计

【1】实验原理

哲学家进餐问题描述的是五个哲学家共用一张圆桌,分别坐在周围的五张椅子上,在圆桌上有五只碗和五只筷子。他们的生活方式是交替地进行思考和进餐。平时,一个哲学家进行思考,饥饿时便试图取用其左右的最靠近他的筷子,只有在他拿到两只筷子时才能进餐。进餐完毕放下筷子继续思考。

由于:①只有拿到两只筷子时,哲学家才能吃饭;②如果筷子已经在他人手上,则该哲学家必须等到他人吃完之后才能拿到筷子;③任何一个哲学家在自己没有拿到两只筷子吃饭之前,决不放下自己手中的筷子。则可能出现五个哲学家都饥饿时都拿着一直筷子。这样就可能五个哲学家都用不上餐。

该问题可用记录型信号量解决,经分析可知,放在桌子上的筷子是临界资源,在一段时间内只允许一位哲学家使用,为了实现对筷子的互斥使用,可以用一个信号量表示一只筷子,由这五个信号量组成信号量数组。当哲学家饥饿时总是先拿其左边的筷子,成功后,再去拿右边的筷子,又成功后方可就餐。进餐完,又先放下他左边的筷子,再放下右边筷子。这个算法可以保证不会有两个相邻的哲学家同时就餐,但有可能引起死锁。

对于死锁问题可采取这样的几种解决方法:

(1)至多只允许四个哲学家同时进餐,以保证至少有一个哲学家可以进餐,最终总会释放出他所用过的两只筷子,从而可使更多的哲学家进餐;

(2)仅当左右两只筷子均可用时,才允许哲学家拿起筷子就餐

(3)规定奇数号哲学家先拿起右边筷子,然后再去拿左边筷子,而偶数号哲学家则相反。

(4)把筷子顺序编号 0, 1, 2, 3, 4,给每个哲学家分配筷子时,必须依从小号到大号(或者相反顺序)进行。

在本次实习里采用第二种方法解决该问题。

【2】数据及程序结构

总共创建有四个类:哲学家进餐问题类,Philosopher类,ChopstickArray

类,Chopstick类。

Chopstick类来表示筷子,其中包括的布尔型成员变量available来表示该筷子是否可用,成员方法setnum()获取其编号;boolean型成员方法isAvailable()返回其当前available的值。setAvailable(boolean available)这一成员方法是对筷子的available的值进行设置,即设置筷子是否可用。

ChopstickArray类用其中的数组chopsticks[i]来存放五只筷子,并通过哲学家的编号及筷子的编号确定该筷子属于当前哲学家的左右哪边的筷子。

Philosopher类,用来描述哲学家,通过实现Runnable接口的方式来创建线程对象,该类中的方法thinking(),eating()来描述哲学家的状态。通过使用关键词synchronized来给共享资源即Philosopher对象上锁,当一个线问程访问Philosopher中的Thinking()时锁定Philosopher对象,这时其他线程就无法访问其另一个方法eating(),即说明哲学家不能同时处于思考和吃饭的状态中。

public synchronized void thinking(){if(state) // 如果在思考,说明这个哲学家两边的筷子没用 \*/{chopstickArray.getnum(num).setAvailable(**true**);chopstickArray.getLast(num).setAvailable(**true**); //这时哲学家两边的筷子只为可用String text = thinkingTextArea.getText();thinkingTextArea.setText(text+**this** + " 在思考\\n");try{Thread.sleep(10000);}catch(Exception e){e.printStackTrace();}}state = **false**; /\*思考完成,进入饥饿状态\*/**public** **synchronized** **void** eating(){**if**(!state) /\* 若不在在思考\*/{**if**(chopstickArray.getnum(num).isAvailable()) /\* 若哲学家右手边的筷子可用\*/{**if**(chopstickArray.getLast(num).isAvailable())/\*如果左手边的筷子也可用,该哲学家状态设为在吃饭,其两侧的筷子都设置为不可用 \*/{chopstickArray.getnum(num).setAvailable(**false**);chopstickArray.getLast(num).setAvailable(**false**);String text = eatingTextArea.getText();eatingTextArea.setText(text+**this** + " 在吃饭\\n");**try**{Thread.*sleep*(10000);}**catch**(Exception e){e.printStackTrace();}}**else**{ /\* 右手边的筷子可用,但是左手边的不可用\*/String str = waitingTextArea.getText();waitingTextArea.setText(str+**this**+" 等待左手边 "+chopstickArray.getLast(num)+"\\n");**try**{wait(**new** Random().nextInt(100));}**catch**(Exception e){e.printStackTrace();}}}**else**{ /\* 如果哲学家右手边的筷子不可用则等待\*/String str = waitingTextArea.getText();waitingTextArea.setText(str+**this**+" 等待右手边 "+chopstickArray.getnum(num)+"\\n");**try**{wait(**new** Random().nextInt(100));}**catch**(Exception e){e.printStackTrace();}}}state = **true**;哲学家进餐问题类建立一个小程序界面。通过一个“程序开始”的按钮,创建出“筷子”和“哲学家”:**public** **void** actionPerformed(ActionEvent e){**if**(e.getActionCommand().equals("程序开始")){ChopstickArray chopstickArray = **new** ChopstickArray(5);/\*五只“筷子”\*/**for**(**int** i = 0; i \< 5; i++){**new** Thread(**new**Philosopher(i,chopstickArray,thinkingTextArea,eatingTextArea, waitingTextArea)).start(); /\*创建五个哲学家线程\*/}}}

五、运行示例及结果分析

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yaT0Kkie-1652198194511)(media/ef59d28ba423c66abe7f6e09cc3eb98b.png)]

首先哲学家0竞争到筷子进入吃饭状态,此时哲学家1和哲学家4无法获得足够筷子,而哲学家3左右筷子可用进入了吃饭状态,此时筷子4、筷子0、筷子2和筷子3不可用。而这时由思考到饥饿的哲学家1和哲学家4只好进入等待状态。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-S0xGoN4H-1652198194513)(media/a2a6dfbbd91a1b72057612f34638cce3.png)]

接下来哲学家0和哲学家3吃完饭其左右筷子进入思考,此时哲学家2饥饿竞争到了起左右筷子进入吃饭状态,饿了的哲学家1只好又等待,此时哲学家4左右筷子可用则进入吃饭状态,没等到筷子的哲学家1只好回去继续思考。

六、总结

本次操作系统实习主要对操作系统一些功能块进行了了解,并通过自己设计小型操作系统模块使得我们对操作系统的了解更加深入。实习中还有对LINUX操作系统内核代码的分析,使我们具体的认识了LINUX,了解其设计思想和功能模块,而在LINUX下的各种常用命令也要求我们熟练掌握。通过实习让我们掌握了更多更详细的操作系统的知识,而且通过自己动手模拟演示其功能,体验操作系统的具体执行。而在编写小程序的时候,在同学们和老师的帮助下解决的了很多的困难。而其中对于多线程的编程对于解决并发性问题高效性也在实习中有了深刻的了解。在实习中我不仅学到了很多的知识,还通过查找解决问题的方法认识到解决问题有时需要不仅是一个人的力量,而是一个整体的力量。这些在我们今天的学习工作生活中是很重要的。最后还要多加感谢实习中同学们和老师的提供帮助。

源程序清单:

**import** java.applet.\*;**import** java.awt.event.\*;**import** java.awt.\*;**import** java.util.Random;**public** **class** 哲学家进餐问题 **extends** Applet **implements** ActionListener,TextListener{**private** Button But1;TextArea thinkingTextArea,eatingTextArea,waitingTextArea;**public** **void** init(){But1 =**new** Button("程序开始");But1.addActionListener(**this**);add(But1);thinkingTextArea = **new** TextArea("思考中:\\n",30, 20);add(thinkingTextArea);eatingTextArea = **new** TextArea("吃饭中:\\n",30, 20);add(eatingTextArea);waitingTextArea = **new** TextArea("等待中:\\n",30, 28);add(waitingTextArea);}**public** **void** actionPerformed(ActionEvent e){**if**(e.getActionCommand().equals("程序开始")){ChopstickArray chopstickArray = **new** ChopstickArray(5);**for**(**int** i = 0; i \< 5; i++){**new** Thread(**new** Philosopher(i,chopstickArray,thinkingTextArea,eatingTextArea, waitingTextArea)).start();}}}**public** **static** **void** main(String[] args){**new** 哲学家进餐问题();}**public** **void** textValueChanged(TextEvent e){// **TODO** Auto-generated method stub}}**class** Philosopher **implements** Runnable /\*哲学家类\*/{**public** Philosopher(**int** num, ChopstickArray chopstickArray,TextArea thinkingTextArea, TextArea eatingtextArea, TextArea waitingTextArea){**this**.num = num;**this**.chopstickArray = chopstickArray;**this**.thinkingTextArea = thinkingTextArea;**this**.eatingTextArea = eatingtextArea;**this**.waitingTextArea = waitingTextArea;}**public** **synchronized** **void** thinking(){**if**(state) /\* 如果在思考,说明这个哲学家两边的筷子没用 \*/{chopstickArray.getnum(num).setAvailable(**true**);chopstickArray.getLast(num).setAvailable(**true**);String text = thinkingTextArea.getText();thinkingTextArea.setText(text+**this** + " 在思考\\n");**try**{Thread.*sleep*(10000);}**catch**(Exception e){e.printStackTrace();}}state = **false**;}**public** **synchronized** **void** eating(){**if**(!state) /\* 若不在在思考\*/{**if**(chopstickArray.getnum(num).isAvailable()) /\* 若哲学家右手边的筷子可用\*/{**if**(chopstickArray.getLast(num).isAvailable())/\*如果左手边的筷子也可用,该哲学家状态设为在吃饭,其两侧的筷子都设置为不可用 \*/{chopstickArray.getnum(num).setAvailable(**false**);chopstickArray.getLast(num).setAvailable(**false**);String text = eatingTextArea.getText();eatingTextArea.setText(text+**this** + " 在吃饭\\n");**try**{Thread.*sleep*(10000);}**catch**(Exception e){e.printStackTrace();}}**else**{ /\* 右手边的筷子可用,但是左手边的不可用\*/String str = waitingTextArea.getText();waitingTextArea.setText(str+**this**+" 等待左手边 "+chopstickArray.getLast(num)+"\\n");**try**{wait(**new** Random().nextInt(100));}**catch**(Exception e){e.printStackTrace();}}}**else**{ /\* 如果哲学家右手边的筷子不可用则等待\*/String str = waitingTextArea.getText();waitingTextArea.setText(str+**this**+" 等待右手边 "+chopstickArray.getnum(num)+"\\n");**try**{wait(**new** Random().nextInt(100));}**catch**(Exception e){e.printStackTrace();}}}state = **true**;}**public** **void** run(){**for**(**int** i = 0; i \< 10; ++i){thinking();eating();}}**public** String toString(){**return** " 哲学家 " + num;}**private** **int** num;**private** **boolean** state;ChopstickArray chopstickArray;TextArea thinkingTextArea;TextArea eatingTextArea;TextArea waitingTextArea;}**class** ChopstickArray /\* 存放筷子类的数组 \*/{**public** ChopstickArray(**int** size){chopsticks = **new** Chopstick[size];**for**(**int** i = 0; i \< chopsticks.length; ++i){chopsticks[i] = **new** Chopstick(i);}}**public** Chopstick getnum(**int** num){**return** chopsticks[num];}**public** Chopstick getLast(**int** num){**if**(num==0){**return** chopsticks[chopsticks.length-1];}**else**{**return** chopsticks[num-1];}}**private** Chopstick[] chopsticks;}**class** Chopstick /\*筷子的类 \*/{**public** Chopstick(**int** num){**this**.num = num;}**public** **boolean** isAvailable(){**return** available;}**public** **void** setAvailable(**boolean** available){**this**.available = available;}**public** **int** getnum(){**return** num;}**public** **void** setnum(**int** num){**this**.num = num;}**public** String toString(){**return** "筷子" + num;}**private** **volatile** **boolean** available = **true**; /\* 表示筷子是否可用 \*/**private** **int** num;}

哲学家进餐问题的模拟【操作系统】相关推荐

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

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

  2. 哲学家进餐问题(java模拟死锁及解决方案)

    一.问题描述 哲学家进餐问题是由 Dijkstra 提出并解决的,该问题是描述有五个哲学家共用一张圆桌,分别坐在周围的五张椅子上,在圆桌上有五个碗和五只筷子,他们的生活方式是交替地进行思考和进餐.平时 ...

  3. 【操作系统】-- PV原语(哲学家进餐问题)

    微信搜索:编程笔记本 微信搜索:编程笔记本 微信搜索:编程笔记本 点击上方蓝字关注我,我们一起学编程 欢迎小伙伴们分享.转载.私信.赞赏 小伙伴儿们看完以后可不可以帮我点亮一下在看呀~ 信号量与进程同 ...

  4. 2.7操作系统(读者—写者问题 哲学家进餐问题 管程 )

    目录 1.读者-写者问题 2.哲学家进餐问题 实现 3.管程 1.为什么要引入管程? ​2.管程的定义和基本特征 3.扩展1:用管程解决生产者消费者问题 4.扩展2:Java中类似于管程的机制  个人 ...

  5. 操作系统:哲学家进餐问题

    哲学家进餐问题 五个哲学家围着一张圆桌,每个哲学家面前放着食物.哲学家的生活有两种交替活动:吃饭以及思考.当一个哲学家吃饭时,需要先拿起自己左右两边的两根筷子,并且一次只能拿起一根筷子. 下面是一种错 ...

  6. 2.3.6 操作系统之进程同步与互斥经典问题(生产者-消费者问题、多生产者-多消费者问题、吸烟者问题、读者-写者问题、哲学家进餐问题)

    文章目录 0.前言 1.生产者-消费者问题 (1)问题描述 (2)问题分析 (3)如何实现? (4)实现互斥的P操作一定要在实现同步的P操作之后 (5)知识回顾与重要考点 2.多生产者-多消费者问题 ...

  7. 操作系统:经典进程同步问题 之 生产者-消费者问题、读者-写者问题、哲学家进餐问题

    在进程同步中,经典的同步问题有:生产者-消费者问题.读者-写者问题.哲学家进餐问题. 一.生产者与消费者问题: 问题描述:使用一个缓冲区来保存物品,只有缓冲区没有满,生产者才可以放入物品:只有缓冲区不 ...

  8. 操作系统之进程管理:15、哲学家进餐问题

    15.哲学家进餐问题 问题描述 解题思路 解决死锁的策略 方案一与方案二 方案三 注 问题描述 解题思路 1.因为需要左手和右手俩只筷子,所以可以直接拿哪只就对哪只上锁 问题:这样的话当每个人都拿走左 ...

  9. java 第六次实验_操作系统第六次实验报告——使用信号量解决哲学家进餐问题...

    0 个人信息 张樱姿 201821121038 计算1812 1 实验目的 通过编程进一步了解信号量. 2 实验内容 在服务器上用Vim编写一个程序:使用信号量解决任一个经典PV问题,测试给出结果,并 ...

  10. 操作系统学习笔记(13) 互斥与同步的经典问题 -哲学家进餐问题

    1 哲学家进餐问题:   2 (算法)信号量方法:   3     //Program diningphilosophers   4     var fork:array[5] of semaphor ...

最新文章

  1. 给机器学习从业者的 12 条建议
  2. Spring内核研究-通过工厂注入
  3. P1131 [ZJOI2007]时态同步
  4. Web测试到底是在测什么(资料合集)
  5. securecrt 乱码_SecureCRT远程连接Linux,配置端点和字节码
  6. Zookeepr 如何进行权限控制?
  7. linux下tar gz bz2 tgz z等众多压缩文件的解压方法
  8. LINUX给进程内容窗口改名的代码
  9. win7虚拟机_虚拟机VMware 14安装步骤
  10. spreadJS初体验
  11. Spring学习-黎活明视频学习注解
  12. 我眼中的无影云桌面‖云桌面使用者角度
  13. 车联网大规模商用关键突破口深度调研车路协同智慧高速全国建设情况
  14. 网络1712--c语言函数作业总结
  15. 致我爱的动漫--Fate 系列 Part 1:《Fate/Zero》
  16. 关于计算机知识的动画电影,动画概论总复习题目(附答案)
  17. Unity-遮挡剔除
  18. 两年多的社招经验分享,我的跳槽经验总结(含阿里滴滴美团快手头条)
  19. Excel应用技巧:不让别人修改你的Excel表
  20. java将链接生成二维码工具类

热门文章

  1. hadoop的filesplit
  2. 2020 年省份数据拉取
  3. mysql 递归表的创建_Mysql创建递归型的存储过程_MySQL
  4. C语言实现通讯录管理系统
  5. vmware tools下载缓慢问题解决
  6. web软件测试 测试报告模板_测试报告模板V1(提供下载)
  7. 国外永久免费5G大容量网盘--SugarSync
  8. 电子设计自动化实验 实验三 频率计制作
  9. 天正CAD启动时显示服务器名称为空,如何解决天正建筑2014启动时出现error
  10. 2021Web前端人事面试题总结精选