操作系统哲学家进餐问题
操作系统实验报告(哲学家问题)
操作系统实验报告实验者:朱毅学号:0701013 实验题目:哲学家问题设有5个哲学家,共享一张放有5把椅子的桌子,每人分得一把椅子。
但是,桌子上总共只有5支筷子,在每人两边分开各放一支。
哲学家们在肚子饥饿时才试图分两次从两边拾起筷子就餐。
条件:(1)只有拿到两支筷子时,哲学家才能吃饭。
(2)如果筷子已在他人手上,则哲学家必须等他人吃完之后才能拿到筷子。
(3)任一哲学家在自己未拿到两支筷子吃饭之前,决不放下自己手中的筷子。
试:(1)描述一个保证不会出现两个邻座同时要求吃饭的通信算法。
(2)描述一个既没有两邻座同时吃饭,又没有人饿死(永远拿不到筷子)的算法。
(3)在什么情况下,5个哲学家全部吃不上饭?开发环境:Microsoft V isual Foxpro 6.0算法描述:数据环境:表KUAIZI 相应字段:筷子号状态(逻辑型)使用者桌号表ZHEXUEJIA相应字段:哲学家名所属状态拥有左筷子(逻辑型)拥有右筷子(逻辑型)桌号表FANGAN 相应字段方案表的具体内容请参见DAIMA.DOC文件本程序解决死锁的关键:从苏格拉底开始往黑格尔依次处理,对每人的处理一次进行到底,从而肯定必然有一人完全占有资源,避免了死锁,其实质就是按照5个哲学家的座位号作为绝对的优先级进行资源的先后分配。
初始状态:选择算法(以下两算法不同之处用黑体标识)算法一:(1)保证不会出现两个邻座同时要求吃饭的通信算法。
1、由操作人员按“有人饿了”按钮,控制是否有哲学家肚子饿了。
2、出现复选框和“确定”按钮,挑选哲学家后,按“确定”后确认选择。
当做出一个选择后,该哲学家左右两边的哲学家则不能被选中(通过对复选框的ENABLED属性控制),若取消选中,则该哲学家左右两边的哲学家(在该哲学家的另一邻居也未被选中为前提) 还原为可选状态。
3、“确认”后执行以下步骤:①从苏格拉底到黑格尔依次检验其是否是此次被选中②若是此次被选中,进行以下步骤:a 改变表KUAIZI 和表ZHEXUEJIA中相应的字段:ZHEXUEJIA:所属状态由F(Full)改为H(Hungry)b执行PROG1,分配给这些饥饿的哲学家筷子,若左边有筷子,取之,并标识“拥有左筷子”;若右边有筷子,取之,并标识“拥有右筷子”。
操作系统课程设计——哲学家进餐问题
操作系统课程设计——哲学家进餐问题1000字哲学家进餐问题是一个经典的多线程同步问题,在操作系统中有着广泛的应用。
因此,在操作系统课程设计中,探究哲学家进餐问题是一件非常有意义的事情。
哲学家进餐问题的场景是:五个哲学家围坐在一张圆桌前,每个哲学家的左右两侧有一只筷子,他们需要利用这两只筷子才能进餐。
每个哲学家有两种状态:思考和进餐。
当一个哲学家处于进餐状态时,他需要同时获取他左右两侧的筷子,进餐结束后,他会释放这两只筷子,进入思考状态。
在这个场景中,如果所有的哲学家都同时想要进餐,那么就可能会出现死锁情况,即所有的哲学家都拿到了左手边的筷子,但都无法拿到右手边的筷子,导致无法进餐。
因此,需要在代码中实现同步互斥机制,避免死锁的发生。
本课程设计中,我使用了Java语言来实现哲学家进餐问题。
在代码实现中,首先定义了哲学家、筷子、餐桌等对象,然后使用线程来模拟哲学家的思考和进餐过程。
为了避免死锁,我使用了Chandy/Misra算法,即每个哲学家先尝试去取左手边的筷子,如果取不到就不再继续等待,而是重新回到思考状态,等待下一个机会。
同时,当一个哲学家取到了左手边的筷子之后,如果发现右手边的筷子已被占用,他就会释放左手边的筷子,重新回到思考状态,等待下一个机会。
在实现过程中,我还使用了信号量机制,保证了线程间的同步互斥。
每个筷子都是一个二元信号量,初始为1,表示可用。
当一个哲学家拿起筷子时,他会将对应的信号量减1,表示不可用。
当哲学家用完筷子之后,会将对应的信号量加1,表示可用。
通过这种方式,实现了对筷子的访问同步。
最后,我对代码进行了测试,模拟了多位哲学家同时进行进餐的过程。
在测试中,我发现哲学家进餐的速度受到筷子的数量和哲学家思考进餐比例的影响。
当筷子数量少于哲学家数量时,容易出现死锁;当哲学家思考和进餐的时间相当时,程序的运行情况比较稳定。
总的来说,本课程设计实现了哲学家进餐问题,通过学习该问题,我更深入地理解了同步互斥机制的重要性,并学会了如何使用信号量来实现同步互斥。
哲学家进餐问题(操作系统)
哲学家进餐问题(操作系统)哲学家进餐问题(操作系统)1. 引言文档概述:在操作系统领域,哲学家进餐问题是一个经典的并发控制问题。
该问题模拟了五位哲学家围坐在一张圆桌旁,每个哲学家面前放置着一碗面和一只叉子。
哲学家在思考和进餐之间切换,但是他们必须分享叉子来进行进餐。
然而,如果每个哲学家都同时拿起右边的叉子,就会出现死锁的情况。
因此,设计一个合理的算法来解决这个问题是非常重要的。
2. 问题描述2.1 哲学家和叉子在该问题中,有五位哲学家分别编号为 P1、P2、P3、P4、P5,以及五只叉子,编号为 F1、F2、F3、F4、F5.每个哲学家在思考时不会使用叉子,而在进餐时需要使用相邻两只叉子。
2.2 运行过程哲学家的运行过程根据以下步骤进行:- 当一个哲学家饿了后,他会尝试获取左边和右边的叉子。
- 如果两只叉子都可用,哲学家就会进餐,并在完成后释放叉子。
- 否则,哲学家需要等待其他哲学家释放叉子。
3. 解决方案为了解决哲学家进餐问题,我们可以采用以下方法之一:3.1 资源分级分配算法该算法将叉子分为左叉子和右叉子,每个哲学家只能同时拿起左叉子和右叉子。
通过约定哲学家只能按照一定顺序拿起叉子,可以避免死锁的发生。
3.2 资源分级分配算法的伪代码:```acquire_forks(left_fork_id, right_fork_id) {if (left_fork_id < right_fork_id) {acquire(left_fork_id);acquire(right_fork_id);} else {acquire(right_fork_id);acquire(left_fork_id);}}release_forks(left_fork_id, right_fork_id) { release(left_fork_id);release(right_fork_id);}philosopher(id) {while (true) {think();acquire_forks(id, (id + 1) % 5);eat();release_forks(id, (id + 1) % 5);}}```4. 附件本文档不涉及附件。
哲学家吃饭问题试验报告操作系统
目录1.设计题目与要求21.1设计目的1.2设计要求2.总体设计思想与相关知识22.1总体设计思想2.2问题描述2.3解决方案3.数据结构、流程图23.1数据结构3.2流程图4.源代码.35.运行结果.66.结果分析.77.总结及心得体会.71.设计题目与要求1.1设计目的掌握进程同步问题的解决思路及方法,熟练使用Windows操作系统提供的信号量机制解决各种进程同步问题.1.2设计要求设有五个哲学家,共用一张放有五把椅子的餐桌,每人坐在一把椅子上,桌子上有五个碗和五只筷子,每人两边各放一只筷子.哲学家们是交替思考和进餐,饥饿时便试图取其左右最靠近他的筷子.条件:(1)只有拿到两只筷子时,哲学家才能吃饭.(2)如果筷子已被别人拿走,那么必须等别人吃完之后才能拿到筷子.(3)任意一个哲学家在自己未拿到两只筷子吃饭前,不会放下手中拿到的筷子.2.总体设计思想与相关知识2.1总体设计思想哲学家的生活就是思考和吃饭,即思考,饿了就餐,再思考,循环往复.要求是:每一个哲学家只有在拿到位于他左右的筷子后,才能够就餐;哲学家只能先拿左边的筷子,再去拿右边的筷子,而不能同时去抓他两边的筷子,也不能从其他哲学家手中抢夺筷子;哲学家每次就餐后必须放下他手中的两把筷子后恢复思考,不能强抓住餐具不放.设计一个程序,能够显示当前各哲学家的状态和桌上餐具的使用情况,并能无死锁的推算出下一状态各哲学家的状态和桌上餐具的使用情况.即设计一个能安排哲学家正常生活的程序.2.2问题描述可能出现死锁问题,由于当五个哲学家都饥饿时,都拿着一支筷子,这样就可能五个哲学家都用不上餐.2.3解决方案2.3.1最多允许4个哲学家同时坐在桌子周围.2.3.2给所有哲学家编号,奇数号的哲学家必须首先拿左边的筷子,偶数号的哲学家那么反之.2.3.3为了防止死锁,把哲学家分为三种状态,思考,饥饿,进食,仅当一个哲学家左右两边的筷子都可用时,才允许他拿筷子,并且一次拿到两只筷子,否那么不拿.3.数据结构及流程图3.1数〞结构philosopherProc+myid:int+mystate:int+philosopherProc(LPVOIDlpParameter)+ResumeThread(hPhilosopher[i]):int +strcpy(stateStr, ""):int程序中定义一个哲学家类,包含两个私有对象和四个公有对象.myid对象:报讯哲学家的编号.mystate对象:用于保存当前该哲学家的状态,philosopherProc( LPVOID lpParameter) 方法:哲学家类构造函数,PHILOSOPHER_NUM表示哲学家编号ResumeThread(hPhilosopher[i]) 方法:返回该哲学家编号strcpy(stateStr,"") 方法:返回哲学家当前状态根据题目要求改变哲学家的状态(饥饿 ,进餐,思考,饥饿)3.2流程图的一个概念.指的是一个核心对象在某一个进程中的唯一索引*/HANDLE semaphore[PHILOSOPHER_NUM]; // semaphore 用来表示筷子是否可用4. 源代码〔c++〕//哲学家就餐问题的解法 #include <windows.h> #include <process.h> #include <time.h> #include <stdlib.h> #include <stdio.h> #include <iostream> using namespace std;有效//命名空间std 内定义的所有标识符都 const unsigned int PHILOSOPHER_NUM=5; //const char THINKING=1;表示得到饥饿,3表示正在吃饭*/ const char HUNGRY=2; const char DINING=3; HANDLE hPhilosopher[5];/*///*HANDLE 〔 哲学家数目标记当前哲学家的状态,1表示等待,2定义数组存放哲学家句柄〕是windows 操作系统中DWORD WINAPI philosopherProc( LPVOID IpParameter) // 据)的API函数philosopherProc {int myid;char idStr[128];char stateStr[128];char mystate;int ret;unsigned int leftFork;//左筷子unsigned int rightFork;//右筷子myid = int(lpParameter);itoa(myid, idStr, 10);WaitForSingleObject(mutex, INFINITE);cout << "philosopher " << myid << " begin" << endl;ReleaseMutex(mutex);mystate = THINKING;//THINKINGHANDLE mutex;// Mutex 用来限制平安输出leftFork = (myid) % PHILOSOPHER_NUM;rightFork = (myid + 1) % PHILOSOPHER_NUM;while (true){switch(mystate){case THINKING:mystate = HUNGRY;//strcpy(stateStr, "HUNGRY");break;case HUNGRY:strcpy(stateStr, "HUNGRY");ret = WaitForSingleObject(semaphore[leftFork], 0); // 可用if (ret == WAIT_OBJECT_0){ret = WaitForSingleObject(semaphore[rightFork], 0); // 再检查右筷子是否可用if (ret == WAIT_OBJECT_0){mystate = DINING;//变自己的状态strcpy(stateStr, "DINING");)else{ReleaseSemaphore(semaphore[leftFork], 1, NULL); // 用,就把左筷子放下改变状态先检查左筷子是否左筷子可用就拿起,右筷子可用,就改如果右筷子不可返回DWORD32位数初始状态为)break;case DINING://吃完后把两支筷子都放下ReleaseSemaphore(semaphore[leftFork], 1, NULL);ReleaseSemaphore(semaphore[rightFork], 1, NULL);mystate = THINKING;//改变自己的状态strcpy(stateStr, "THINKING");break;)// 输出状态WaitForSingleObject(mutex, INFINITE);cout << "philosopher " << myid << " is : " << stateStr << endl;ReleaseMutex(mutex);// sleep a random time : between 1 - 5 sint sleepTime;sleepTime = 1 + (int)(5.0*rand()/(RAND_MAX+1.0));Sleep(sleepTime*10);))int main(){int i;srand(time(0));mutex = CreateMutex(NULL, false, NULL);for (i=0; i<PHILOSOPHER_NUM; i++){semaphore[i] = CreateSemaphore(NULL, 1, 1, NULL);hPhilosopher[i]=CreateThread(NULL,0,philosopherProc,LPVOID(i), CREATE_SUSPENDED,0);)for (i=0; i<PHILOSOPHER_NUM; i++)ResumeThread(hPhilosopher[i]);Sleep(2000);return 0;)5.运行结果6.结果分析对哲学家进行编号,将他们的初始状态全部设定为THINGKING接着先从0开始改变他们的状态为HUNGRY继续运行后4号和2号哲学家先DINING, 3号和1号哲学家为HUNGRY当4号哲学家吃完后,0号哲学家就开始DINING7.总结及心得体会这次操作系统的作业让我深刻的体会到操作系统的知识作用.培养我综合运用知识的水平,结合了C++的知识来解决这个问题.稳固了以前的知识.在设计这个程序的时候我遇到了很多困难,但是通过老师和同学们的帮助,我一一解决掉了.而且发现了我很多学习中的缺乏之处,对以前学习的知识熟悉不够深刻,掌握的不够,这个要好好复习一下.总的来说,这个操作系统的作业带给我很多收获,让我受益匪浅.封pliilcsopher.cpp附件:。
计算机操作系统哲学家进餐问题的教学探讨
计算机操作系统哲学家进餐问题的教学探讨
计算机操作系统哲学家进餐问题是一个经典的模拟问题,用于帮助学生理解线程同步、死锁和资源管理等操作系统的核心概念。
该问题描述了n个哲学家围坐在一张圆桌周围,每个哲学家面前有一盘食物,中间有n个筷子。
哲学家需要吃饭,但是每个哲学家只能使用自己左右两边的筷子来进餐。
如果哲学家发现左边或右边的筷子被占用,就会等待,直到筷子被释放。
这个问题中存在死锁的可能性。
在教学中,可以通过演示代码或编写代码来模拟这个问题的运行情况,帮助学生理解这些概念的实际应用。
例如,可以演示如何使用锁和条件变量来解决死锁问题,或者如何
使用信号量管理系统资源来避免死锁问题。
另外可以讨论不同的算法和策略,如顺序获取筷子,随机获取筷子等,来说明如何避免死锁的发生.
总之,通过这个问题的模拟,学生可以加深对操作系统的理解,并且对如何解决多线程并发问题有更深入的了解。
在教学探讨中,老师可以通过不同的模拟实验来说明线程同步和死锁的本质原理以及如何避免和解决这些问题。
鼓励学生进行自己的实验和探究,以加深对这些概念的理解。
操作系统哲学家就餐问题课程设计c语言
1.1 设计题目描述:
用多线程同步方法解决哲学家就餐问题(Dining-Philosophers Problem)
1.2 要求:
1)为每个哲学家产生一个线程,设计正确的同步算法 2)每个哲学家取得一双筷子开始用餐后,即时显示“Dining…”和该哲学 家的自定义标识符以及餐桌上所有几位哲学家标识符及其所坐的位置。 3)设定共有 5 个哲学家需用餐。每位用餐耗时 10 秒钟以上。 4)多个哲学家须共享操作函数代码。
针对每个哲学家通过共享操作函数代码分别建立5个线程以实现同步哲学家就餐而申请进入餐厅的哲学家进入room的等待队列根据fifo的原则总会进入到餐厅就餐因此不会出现饿死和死锁的现象针对5只筷子分别设置了5个互斥信号量以保证每只筷子每次只能被取得一次
武汉理工大学《操作系统》课程设计
题 目 : 用 多 线 程 同 步 方 法 解 决 哲 学 家 就 餐 问 题 (Dining-Philosophers
2. 设计说明书内容要求: Nhomakorabea1)设计题目与要求 2)总的设计思想及系统平台、语言、工具等。 3)数据结构与模块说明(功能与流程图) 4) 给出用户名、 源程序名、 目标程序名和源程序及其运行结果。 (要 注明存储各个程序及其运行结果的 Linux 主机 IP 地址和目录。 ) 5)运行结果与运行情况 (提示: (1)连续存储区可用数组实现。 (2)编译命令可用: cc (3)多线程编程方法参见附件。 )
2.2 系统平台、语言及工具
(1)操作系统:Linux (2)程序设计语言:C 语言 (3)工具:编辑工具 Vi、编译器 gcc
1
武汉理工大学《操作系统》课程设计
3.数据结构与模块说明
线程创建函数 pthread_create 声明如下: #include <pthread.h> int pthread_create (pthread_t *thread,pthread_attr_t *attr,Void* (*start_routine)(void *),void *arg);
哲学家进餐问题和银行家算法
哲学家进餐问题和银行家算法是操作系统中的经典问题,都涉及到资源分配和死锁的问题。
哲学家进餐问题是关于死锁的经典问题。
假设有五位哲学家坐在一张圆桌周围,他们轮流思考和吃饭。
吃饭的时候,他们需要使用两边的筷子。
问题是,如果哲学家们在拿起左边的筷子之前必须等待右边的筷子可用,那么有可能发生死锁。
例如,如果每个哲学家都拿起左边的筷子并等待右边的筷子,那么就会出现循环等待的情况,导致所有人都饿死,这就是死锁。
为了避免这种情况,操作系统需要一种机制来避免死锁,比如规定哲学家们必须按照固定的顺序拿起筷子等。
银行家算法是关于资源分配和避免死锁的算法。
该算法模拟了银行贷款的场景,通过检查请求是否会导致死锁来决定是否分配资源。
如果分配资源会导致死锁,算法就会拒绝该请求;否则,它就会分配资源。
银行家算法需要在操作系统中进行配置,以便动态管理资源的分配,并在需要时回收资源以避免死锁。
这两个问题的解决方法是操作系统中的重要组成部分,旨在确保系统中的多个进程或线程能够公平地共享资源,并避免出现死锁等不期望的情况。
操作系统实验报告哲学家就餐
操作系统实验报告哲学家就餐一、实验目的:通过模拟哲学家就餐问题,了解并掌握操作系统中的进程同步机制,以及解决进程间资源竞争所引发的死锁问题。
二、实验介绍:哲学家就餐问题是由荷兰计算机科学家伊克斯特拉(Dijkstra)于1965年首次提出的。
其问题描述如下:五位哲学家坐在一张圆桌子周围,每个哲学家面前有一碗饭和一根筷子。
哲学家的生活方式是交替地进行思考和进食。
当一个哲学家思考时,他不需要使用他的两个筷子;当一个哲学家想吃饭时,他需要同时获取他的左右两个筷子,并在获取到筷子后才能开始进食。
问题的关键是如何解决哲学家间的筷子竞争问题,以及避免死锁的发生。
三、实验设计:1.并发思路每个哲学家作为一个进程,在进行思考和进食这两个操作之前,需要获取他的两个筷子。
接下来考虑进程同步的两个关键点:-互斥:保证每个筷子同时只能被一个哲学家使用,避免资源竞争问题。
-死锁避免:通过限制只允许至多四位哲学家同时持有筷子,从而避免死锁发生。
2.进程同步机制- 互斥:使用Semaphore实现互斥,每个筷子都是一个Semaphore,初始值为1-死锁避免:引入一个全局计数器,记录当前持有筷子的哲学家数量,每次哲学家想要获取筷子时,先检查该计数器,仅当计数器小于4时才会获取筷子。
四、实验步骤:1.创建5个哲学家进程和5个筷子线程。
2.每个哲学家的线程循环执行思考和进食操作。
3.在进食之前,哲学家需要获取两个筷子,获取筷子的顺序按照哲学家编号进行,每个哲学家先获取自己的左边筷子,再获取自己的右边筷子。
4.进行进食操作后,哲学家释放两个筷子。
5.循环执行步骤3和步骤4,直到实验结束。
五、实验结果:通过观察实验结果,可以看到哲学家的思考和进食操作交替进行,并且避免了死锁的发生。
六、实验总结:通过本次实验,我了解了操作系统中的进程同步机制,并学会了如何解决资源竞争和死锁问题。
在本实验中,我使用了Semaphore和全局计数器实现了互斥和死锁避免,从而成功模拟了哲学家就餐问题。
操作系统哲学家进餐问题
操作系统实习报告一、设计目的:死锁是进程并发执行过程中可能出现的现象,所谓死锁,是指多个进程在运行过程中因争夺资源而造成的一种僵局。
哲学家就餐问题是描述死锁的经典例子。
为了防止死锁,可以采用资源预分配法或者资源按序分配法。
资源预分配法是指进程在运行前一次性地向系统申请它所需要的全部资源,如果系统当前不能够满足进程的全部资源请求,则不分配资源, 此进程暂不投入运行,如果系统当前能够满足进程的全部资源请求, 则一次性地将所申请的资源全部分配给申请进程。
二、设计内容哲学家进餐问题的模拟。
三、开发环境windows环境,Myeclipse平台。
四、分析设计<一>实验原理哲学家进餐问题描述的是五个哲学家共用一张圆桌,分别坐在周围的五张椅子上,在圆桌上有五只碗和五只筷子。
他们的生活方式是交替地进行思考和进餐。
平时,一个哲学家进行思考,饥饿时便试图取用其左右的最靠近他的筷子,只有在他拿到两只筷子时才能进餐。
进餐完毕放下筷子继续思考。
由于:①只有拿到两只筷子时,哲学家才能吃饭;②如果筷子已经在他人手上,则该哲学家必须等到他人吃完之后才能拿到筷子;③任何一个哲学家在自己没有拿到两只筷子吃饭之前,决不放下自己手中的筷子。
则可能出现五个哲学家都饥饿时都拿着一直筷子。
这样就可能五个哲学家都用不上餐。
该问题可用记录型信号量解决,经分析可知,放在桌子上的筷子是临界资源,在一段时间内只允许一位哲学家使用,为了实现对筷子的互斥使用,可以用一个信号量表示一只筷子,由这五个信号量组成信号量数组。
当哲学家饥饿时总是先拿其左边的筷子,成功后,再去拿右边的筷子,又成功后方可就餐。
进餐完,又先放下他左边的筷子,再放下右边筷子。
这个算法可以保证不会有两个相邻的哲学家同时就餐,但有可能引起死锁。
对于死锁问题可采取这样的几种解决方法:(1)至多只允许四个哲学家同时进餐,以保证至少有一个哲学家可以进餐,最终总会释放出他所用过的两只筷子,从而可使更多的哲学家进餐;(2)仅当左右两只筷子均可用时,才允许哲学家拿起筷子就餐(3)规定奇数号哲学家先拿起右边筷子,然后再去拿左边筷子,而偶数号哲学家则相反。
哲学家吃饭问题 实验报告 操作系统
欢迎共阅目录1.设计题目与要求 (2)1.1设计目的1.2设计要求2.总体设计思想与相关知识 (2)2.1总体设计思想2.2问题描述2.3解决方案3.数据结构、流程图 (2)3.1数据结构3.2流程图4.源代码 (3)5.运行结果 (6)6.结果分析 (7)7.总结及心得体会 (7)1.设计题目与要求1.1设计目的掌握进程同步问题的解决思路及方法,熟练使用Windows操作系统提供的信号量机制解决各种进程同步问题。
1.2设计要求设有五个哲学家,共用一张放有五把椅子的餐桌,每人坐在一把椅子上,桌子上有五个碗和五只筷子,每人两边各放一只筷子。
哲学家们是交替思考和进餐,饥饿时便试图取其左右最靠近他的筷子。
条件:(1) 只有拿到两只筷子时,哲学家才能吃饭。
(2) 如果筷子已被别人拿走,则必须等别人吃完之后才能拿到筷子。
(3) 任意一个哲学家在自己未拿到两只筷子吃饭前,不会放下手中拿到的筷子。
2.总体设计思想与相关知识2.1总体设计思想哲学家的生活就是思考和吃饭,即思考,饿了就餐,再思考,循环往复。
要求是:每一个哲学家只有在拿到位于他左右的筷子后,才能够就餐;哲学家只能先拿左边的筷子,再去拿右边的筷子,而不能同时去抓他两边的筷子,也不能从其他哲学家手中抢夺筷子;哲学家每次就餐后必须放下他手中的两把筷子后恢复思考,不能强抓住餐具不放。
设计一个程序,能够显示当前各哲学家的状态和桌上餐具的使用情况,并能无死锁的推算出下一状态各哲学家的状态和桌上餐具的使用情况。
即设计一个能安排哲学家正常生活的程序。
2.2问题描述可能出现死锁问题,因为当五个哲学家都饥饿时,都拿着一支筷子,这样就可能五个哲学家都用不上餐。
2.3解决方案2.3.1 最多允许4个哲学家同时坐在桌子周围。
2.3.2 给所有哲学家编号,奇数号的哲学家必须首先拿左边的筷子,偶数号的哲学家则反之。
2.3.3 为了避免死锁,把哲学家分为三种状态,思考,饥饿,进食,仅当一个哲学家左右两边的筷子都可用时,才允许他拿筷子,并且一次拿到两只筷子,否则不拿。
计算机操作系统哲学家进餐问题的教学探讨
有五个哲学家,共用一张圆桌,分别坐在周围的五把 椅子上,圆桌上有五个碗和五只筷子,每人两边各放一只 筷子,如图 1 所示。哲学家们是交替思考和进餐,饥饿时 便试图取其左右最靠近他的筷子。
图 1 哲学家进餐描述图 哲学家进餐问题可看作是并发进程并发执行时,处理 共享资源的一个有代表性的问题。分析其约束条件: (1) 只有拿到两只筷子时,哲学家才能吃饭。
用面向对象的思想,将资源及资源的共享操作封装起来, 用管程来管理,实现哲学家进餐问题,使用起来更加方便。
算法实现描述如下:
4.1 建立管程
philosopher (int I) { while (true) { 思考; wait (count); wait(chopstick[I ]); wait(chopstick[I+1]mod 5); 进餐; signal(chopstick[I]); signal(chopstick[I+1]mod 5) signal(count) } }
signal (chopstick[I +(I % 2)]); signal (chopstick[(I+ (I+1) % 2) % 5] );
}
}
87
Computer Education 教学研究与教材建设
解法二:至多允许四位哲学家进餐,将最后一个哲学 家停止申请资源,断开环路。最终能保证有一位哲学家能 进餐,用完释放两只筷子,从而使更多的哲学家能够进餐。 增加一个信号量定义 semaphore count = 4;算法描述第 I 个哲学家的活动:
当五个哲学家同时去取他左边的筷子,每人拿到一只 筷子且不释放,即五个哲学家只得无限等待下去,引起 死锁。
3.2 死锁问题的解决
进程同步与互斥_哲学家进餐问题
2.1总体设计思想
哲学家的生活就是思考和吃饭,即思考,饿了就吃,吃饱了再思考,循环往复。要求是:每一个哲学家只有在拿到位于他左右两侧的筷子后,才能够就餐;哲学家不能拿着一只筷子不放手,也不能从其他哲学家手中抢夺筷子;哲学家每次吃饱后必须放下他手中的两只筷子恢复思考,不能强抓住筷子不放。
设计一个程序,能够显示当前各哲学家的状态和桌上筷子的使用情况,并能无死锁的推算出下一状态各哲学家的状态和桌上筷子的使用情况。即设计一个能安排哲学家正常生活的程序。
4
using System;
using System.Collections.Generic;
using ponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
3.退出区:清除临界区被占用的标志
4.剩余区:进程与临界区不相关部分的代码
2.2系,是为完成某种任务而建立的两个或多个线程,这个线程需要在某些位置上协调他们的工作次序而等待、传递信息所产生的制约关系。进程间的直接制约关系来源于他们之间的合作。
比如说进程A需要从缓冲区读取进程B产生的信息,当缓冲区为空时,进程B因为读取不到信息而被阻塞。而当进程A产生信息放入缓冲区时,进程B才会被唤醒。概念如下图所示。
for (int i = 0; i < 5; i++)
{
pts = new ParameterizedThreadStart(Eating);
m_thread[i] = new Thread(pts);
}
Philospher ph = new Philospher();
操作系统专业课程设计哲学家进餐问题
目录1.设计题目和要求 .................................. 错误!未定义书签。
1.1试验目标和设计要求 ..................... 错误!未定义书签。
1.2 初始条件........................................ 错误!未定义书签。
2 总体设计思想及相关知识 .................... 错误!未定义书签。
2.1总体设计思想................................. 错误!未定义书签。
2.2 临界区互斥编程原理 .................... 错误!未定义书签。
2.3开发环境和工具............................. 错误!未定义书签。
3数据结构和模块说明 ............................. 错误!未定义书签。
3.1 数据结构........................................ 错误!未定义书签。
3.2程序各模块步骤图 ......................... 错误!未定义书签。
3.2.1 主程序模块............................ 错误!未定义书签。
3.2.2 状态改变模块........................ 错误!未定义书签。
3.2.3 返回哲学家状态模块 ............ 错误!未定义书签。
3.2.4 返回餐具状态模块................ 错误!未定义书签。
4. 源程序代码 ......................................... 错误!未定义书签。
5. 测试及结果........................................... 错误!未定义书签。
6. 课设总结............................................... 错误!未定义书签。
哲学家进餐问题(操作系统)
哲学家进餐问题(操作系统)哲学家进餐问题(操作系统)1.简介1.1 背景介绍哲学家进餐问题是计算机科学中一个经典的并发问题,最早由Edsger Dijkstra在1965年提出。
1.2 问题描述问题的场景是五位哲学家围坐在一张圆桌前,每个哲学家面前有一碗饭和一根筷子。
哲学家需要交替地思考和进餐,但是他们只能使用左右两边的筷子来进餐。
1.3 目标设计一个算法来保证哲学家们能够交替地进餐,同时避免死锁和饥饿现象的发生。
2.解决方案2.1 简单解法一个简单的解法是给每个哲学家编号,规定奇数号哲学家先拿左边的筷子,偶数号哲学家先拿右边的筷子。
当一个哲学家需要拿筷子时,他会先检查他的两边是否有其他哲学家正在使用,如果没有,他就可以拿起两边的筷子进餐。
否则,他需要等待直到两边的筷子都可用。
2.2 改进解法上述简单解法可能会导致死锁问题。
为了避免死锁,我们可以引入资源分级的概念。
每个筷子被分为两个等级,分别是主要资源和次要资源。
哲学家需要按照顺序来获取资源,例如,先获取主要资源,然后获取次要资源。
3.算法实现3.1 数据结构我们可以使用一个数组来表示圆桌上的五个筷子,同时使用一个锁数组来表示每个筷子的状态(是否被占用)。
3.2 算法流程在哲学家进餐问题中,每个哲学家都需要经历思考和进餐两个过程,我们可以使用线程来模拟这两个过程。
4.算法分析4.1 死锁问题通过引入资源分级的概念,我们成功避免了死锁问题的发生。
每个哲学家按照顺序获取资源,不会出现他们都在等待同一个资源的情况。
4.2 饥饿问题在我们的算法中,每个哲学家都会交替地进餐和思考,因此不会出现饥饿问题。
5.附件本文档暂无附件。
6.法律名词及注释6.1 死锁死锁是指在并发系统中,两个或多个进程或线程无限期地互相等待对方所占有的资源的情形。
6.2 饥饿饥饿是指某个进程或线程因无法获得所需的资源而无法继续执行的情况。
哲学家进餐问题
8
哲学家进餐问题的应用
操作系统线程同步 生活中人行马路同步
9
感谢您的阅读收藏,谢谢!
7
解决问题的办法
A.原理:至多只允许四个哲学家同时进餐,以保 证至少有一个哲学家能够进餐,最终总会释放出他 所使用过的两支筷子,从而可使更多的哲学家进餐。 以下将room 作为信号量,只允许4 个哲学家同时 进入餐厅就餐,这样就能保证至少有一个哲学家 可以就餐,而申请进入餐厅的哲学家进入room 的 等待队列,根据FIFO 的原则,总会进入到餐厅就 餐,因此不会出现饿死和死锁的现象。
5
以上两个问题反映的是程序并发执行时进 程同步的两个关键问题:饥饿和死锁。为 了提高系统的处理能力和机器的利用率, 并发程序被广泛地使用,因此,必须彻底 解决并发程序执行中的死锁和饥饿问题。
6
于是,哲学家问题推广为更一般性的n个进 程和m个共享资源的问题,并在研究过程中 给出了解决这类的问题的不少方法和工具, 如Pertri网、并发程序设计语言等。
如何协调5位置学家的生活进程,使得每位 哲学家最终都可以进餐?
4
考虑下面的两种情况。
(1)哲学家的生活进程,当所有的哲学家都同时 拿起左手筷子时,则所有哲学家都将拿不到右手 筷子,并处于等待状态,那么,哲学家都将无法 进餐,最终饿死。
(2)将哲学家的生活进程修改为当拿不到右手筷 子时,就放下左手筷子。但是,可能在一个瞬间, 所有的哲学家都同时拿起左手筷子,则自然拿不 到右手筷子,于是同时放下左手筷子,等一会, 又同时拿起左手筷子,如此重复下去,则所有的 哲学家都将无法进餐。
哲学家进餐
哲学家供餐问题是计算机科学家递杰斯 特拉提出的,问题是这样描述的:人的面 前有一碗面条,碗的两旁各有一只筷子.假 设哲学家的生活除了吃饭就是思考问题, 吃饭的时候需要左手拿一只筷子,右手拿 一只筷子,然后开始进餐。吃完后将两只 筷子放回原处,继续思考问题。
操作系统(哲学家进餐问题)
操作系统(哲学家进餐问题)哲学家进餐问题:有五个哲学家,他们的⽣活⽅式是交替地进⾏思考和进餐。
哲学家们共⽤⼀张园桌,分别坐在周围五张椅⼦上。
在圆桌上五⽀筷⼦,平时⼀个哲学家进⾏思考,饥饿时便试图取⽤其左右最靠近他的筷⼦,只有在他拿到两⽀筷⼦时才能进餐。
进程毕,放下筷⼦⼜继续思考。
问题分析:筷⼦是临界资源,⼀次只能被⼀个哲学家使⽤。
因此,五个⼈不能同时拿起左边的筷⼦(或右边)否则或引起死锁。
解决⽅案:(1)⾄多只允许四位哲学家同时拿左边的筷⼦,最终保证有⼀位哲学家能够进餐,并且⽤完能够释放筷⼦,让更多的哲学家进餐。
(2)仅当哲学家左右两只筷⼦都可以⽤的时候,才允许拿筷⼦进餐。
semaphore chopstick[5]={1,1,1,1,1};//五个信号量,⼀个信号量代表⼀只筷⼦semaphore mutex=1;Pi(){while(1){wait(mutex);//设置信号量,防⽌其它⼈争夺资源wait(chopstick[i]);wait(chopstick[(i+1)%5]);signal(mutex);//拿到两只筷⼦后释放信号量吃饭;signal(chopstick[i]);//吃过饭后,释放筷⼦资源signal(chopstick[(i+1)%5]);}}(3)奇数号哲学家先拿左边的,再拿右边的;偶数则相反。
即五位哲学家都先竞争奇数号筷⼦,获得后再去竞争偶数号筷⼦,最终总会有⼀位哲学家有两只筷⼦。
semaphore chopstick[5]={1,1,1,1,1};Pi(){while(1){if(i%2!=0){//奇数号哲学家wait(chopstick[i]);//拿左边的wait(chopstick[(i+1)%5]);//右边的}else{//偶数号哲学家wait(chopstick[(i+1)%5]);//右边的wait(chopstick[i]);//左边的}进餐;signal(chopstick[i]);//释放筷⼦资源signal(chopstick[(i+1)%5]);}}。
操作系统 哲学家进餐问题 读者—写者问题
读者—写者问题 8.3.4 读者 写者问题
有两组并发进程: 有两组并发进程 读者和写者,共享一组数据区 要求: 要求: 允许多个读者同时执行读操作 不允许读者、写者同时操作 不允许多个写者同时操作
12
读者—写者问题 8.3.4 读者 写者问题
读者--写者问题有两种类型: 读者 写者问题有两种类型: 写者问题有两种类型 第一类:读者优先- 第一类:读者优先-附解
①full:初值为 的信号量,表示缓冲区中已有的物品个数; 的信号量, :初值为0的信号量 表示缓冲区中已有的物品个数;
的信号量, ②empty:初值为 的信号量,表示缓冲区中可供使用的缓冲区数目; :初值为k的信号量 表示缓冲区中可供使用的缓冲区数目; 的信号量, ③mutex:初值为 的信号量,用于互斥使用缓冲区; :初值为1的信号量 用于互斥使用缓冲区;
Producer( ): while(TRUE) { 生产一个物品; 生产一个物品 P(empty); P(mutex);
/* 申请缓冲区里的空位 */ /* 进入临界区 */ /* 生产者进程程序 */
Consumer( ): { P(full); P(mutex);
/* 消费者进程程序 */
/* 缓冲区里有物品吗?*/ /* 进入临用数据时, 用数据时,其他读 者都不能使用该数 据,这不符合题目 要求。
8.3.4 读者—写者问题
(2) 判定是否是第 个读者 判定是否是第1个读者 希望在读者进程里, 希望在读者进程里,有一个办法能判定请求进入临界区 的是否是第1个读者。如果是第1个读者 个读者, 的是否是第 个读者。如果是第 个读者,就对信号量 wrt做 个读者 做 P操作, 以取得和写者的互斥 ; 如果是后继读者 , 就不再对 操作,以取得和写者的互斥;如果是后继读者, 操作 wrt 做P操作。 操作。 操作 为此, 它不是信号量)初值为 为此 , 设变量 first(它不是信号量 初值为 。 任何一个 它不是信号量 初值为0。 读者运行时,都先在first上加 ,然后判定它是否取值为 。 上加1,然后判定它是否取值为1。 读者运行时,都先在 上加 若是1,则做 否则不做。如图所示。 若是 ,则做P(wrt) ,否则不做。如图所示。
操作系统哲学家就餐问题实验报告
操作系统哲学家就餐问题实验报告实验目的:通过实验探究操作系统中的哲学家就餐问题,了解并掌握解决该问题的不同算法。
实验原理:哲学家就餐问题是一个典型的并发控制问题,该问题描述了一群哲学家围坐在圆桌上,每个哲学家左右两边各有一只筷子,哲学家只有同时拿到左右两只筷子时才能进餐,进餐完毕后将筷子放回桌面。
该问题的解决涉及到互斥、死锁、饥饿等并发问题。
实验步骤:1. 实现基于信号量的解法:- 为每个哲学家和筷子创建一个信号量;- 哲学家进入就餐前先检查左右两只筷子是否可用;- 若可用,则将左右两只筷子设置为不可用,并进餐;- 进餐完毕后将左右两只筷子设置为可用。
2. 实现基于管程的解法:- 哲学家类中定义进餐和放下筷子的方法;- 使用一个互斥锁来确保每次只有一个哲学家能进入管程;- 当某个哲学家想要进餐时,先检查是否有足够的筷子可用;- 若可用,则进入进餐方法,将筷子设置为不可用,并开始进餐; - 进餐完毕后,释放筷子并通知其他哲学家。
3. 运行实验程序,观察哲学家的就餐过程。
4. 分析实验结果,比较两种算法的优缺点。
实验结果与分析:通过观察实验程序运行的结果,可以发现在基于信号量的解法中,哲学家的就餐过程是以并发的方式进行的,每个哲学家在不产生死锁的前提下获取到筷子并进餐。
但是,由于每个哲学家只能同时拿到一只筷子,有可能会出现饥饿的情况,即某个哲学家一直无法获取到筷子进餐。
而基于管程的解法则能够避免饥饿的问题,每个哲学家在进餐前都会检查是否有足够的筷子可用,若不可用则等待。
通过互斥锁的使用,确保每次只有一个哲学家能够进入管程进行操作,避免了并发产生的问题。
综上所述,基于管程的解法相对于基于信号量的解法更加可靠,能够避免饥饿问题的出现。
但是在实际应用中,两种解法的选择还需要根据具体情况进行权衡和取舍。
哲学家进餐问题(操作系统)
哲学家进餐问题(操作系统)哲学家进餐问题(操作系统)介绍:哲学家进餐问题是一个经典的并发算法问题,旨在解决多个哲学家在共享资源(餐叉)上发生死锁的可能性。
这个问题可以帮助我们理解操作系统中的并发问题和资源分配策略。
1、问题描述问题中有N个哲学家坐在一个圆桌周围,每个哲学家面前有一盘食物和一支餐叉。
哲学家的生活可以分为思考和进餐两个状态。
当哲学家进餐时,他需要同时拿起他左右两边的餐叉,进食完毕后再放下餐叉进行思考。
2、算法设计为了解决哲学家进餐问题中的死锁问题,可以采用以下算法设计:2.1、餐叉限制为了避免死锁问题,可以引入餐叉限制策略。
每个哲学家一开始只能拿起右手边的餐叉,在用餐完毕后再放下餐叉,然后才能拿起左手边的餐叉。
这样,如果每个哲学家都只拿起右手边的餐叉,不会出现餐叉死锁的情况。
2.2、同时判断两个餐叉是否可用为了避免哲学家同时拿起两个餐叉造成资源竞争问题,可以引入一个全局锁,每次只有一个哲学家可以同时判断两个餐叉是否可用并取走。
3、代码实现以下是解决哲学家进餐问题的伪代码实现:```initialize();while (true) {think(); // 哲学家思考pickup_forks(); // 拿起餐叉eat(); // 哲学家进食putdown_forks(); // 放下餐叉}```4、系统流程图以下是哲学家进餐问题的系统流程图:(此处添加哲学家进餐问题的系统流程图)5、相关附件本文档未附带相关附件,请根据实际需求添加。
6、法律名词及注释本文档没有涉及法律名词及注释。
《哲学家进餐问题操作系统》课件模板
signal (fork[ i + 1 ] mod 5) ;
signal (fork[ i]) ;
}
Else
//奇数哲学家,先左后右。
{
wait (fork[ i]) ;
wait (fork[ i + 1 ] mod 5) ;
eat();
signal (fork[ i]) ;
signal (fork[ i + 1 ] mod 5) ;
算法改善:
至多只允许四个哲学家同时进餐,以保 证至少有一个哲学家能够进餐,最终总会释 放出他所使用过的两支筷子,从而可使更多 的哲学家进餐。
改进后的算法A
semaphore fork[5]={1,1,1,1,1};
semaphore room=4;
void philosopher(int i)
{
算法 A
void philosopher(int i) /*i:哲学家编号,从0 到4*/
{
while (TRUE)
{
think( );
/*哲学家正在思考*/
take_fork(i);
/*取左侧的筷子*/
take_fork((i+1) % N); /*取右侧筷子;%为取模运算*/
eat( );
/*吃饭*/
哲学家进餐问题操作系统
(Excellent handout training template)
问题描述
设有五个哲学家,共用一张放有五把椅子 的餐桌,每人坐在一把椅子上,桌子上有五个 碗和五只筷子,每人两边各放一只筷子。哲学 家们是交替思考和进餐,饥饿时便试图取其左 右最靠近他的筷子。
0 1
4
3
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
操作系统实习报告一、设计目的:死锁是进程并发执行过程中可能出现的现象,所谓死锁,是指多个进程在运行过程中因争夺资源而造成的一种僵局。
哲学家就餐问题是描述死锁的经典例子。
为了防止死锁,可以采用资源预分配法或者资源按序分配法。
资源预分配法是指进程在运行前一次性地向系统申请它所需要的全部资源,如果系统当前不能够满足进程的全部资源请求,则不分配资源, 此进程暂不投入运行,如果系统当前能够满足进程的全部资源请求, 则一次性地将所申请的资源全部分配给申请进程。
二、设计内容哲学家进餐问题的模拟。
三、开发环境windows环境,Myeclipse平台。
四、分析设计<一>实验原理哲学家进餐问题描述的是五个哲学家共用一张圆桌,分别坐在周围的五张椅子上,在圆桌上有五只碗和五只筷子。
他们的生活方式是交替地进行思考和进餐。
平时,一个哲学家进行思考,饥饿时便试图取用其左右的最靠近他的筷子,只有在他拿到两只筷子时才能进餐。
进餐完毕放下筷子继续思考。
由于:①只有拿到两只筷子时,哲学家才能吃饭;②如果筷子已经在他人手上,则该哲学家必须等到他人吃完之后才能拿到筷子;③任何一个哲学家在自己没有拿到两只筷子吃饭之前,决不放下自己手中的筷子。
则可能出现五个哲学家都饥饿时都拿着一直筷子。
这样就可能五个哲学家都用不上餐。
该问题可用记录型信号量解决,经分析可知,放在桌子上的筷子是临界资源,在一段时间内只允许一位哲学家使用,为了实现对筷子的互斥使用,可以用一个信号量表示一只筷子,由这五个信号量组成信号量数组。
当哲学家饥饿时总是先拿其左边的筷子,成功后,再去拿右边的筷子,又成功后方可就餐。
进餐完,又先放下他左边的筷子,再放下右边筷子。
这个算法可以保证不会有两个相邻的哲学家同时就餐,但有可能引起死锁。
对于死锁问题可采取这样的几种解决方法:(1)至多只允许四个哲学家同时进餐,以保证至少有一个哲学家可以进餐,最终总会释放出他所用过的两只筷子,从而可使更多的哲学家进餐;(2)仅当左右两只筷子均可用时,才允许哲学家拿起筷子就餐(3)规定奇数号哲学家先拿起右边筷子,然后再去拿左边筷子,而偶数号哲学家则相反。
(4)把筷子顺序编号0, 1, 2, 3, 4,给每个哲学家分配筷子时,必须依从小号到大号(或者相反顺序)进行。
在本次实习里采用第二种方法解决该问题。
<二>数据及程序结构总共创建有四个类:哲学家进餐问题类,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();/*创建五个哲学家线程*/}}}五.运行示例及结果分析首先哲学家0竞争到筷子进入吃饭状态,此时哲学家1和哲学家4无法获得足够筷子,而哲学家3左右筷子可用进入了吃饭状态,此时筷子4、筷子0、筷子2和筷子3不可用。
而这时由思考到饥饿的哲学家1和哲学家4只好进入等待状态。
接下来哲学家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 implementsActionListener,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(newPhilosopher(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;}。