6个哲学家进餐问题预防死锁

合集下载

哲学家进餐问题的趣味例子

哲学家进餐问题的趣味例子

哲学家进餐问题的趣味例子
哲学家进餐问题是一个经典的计算机科学问题,用来展示并发编程中可能出现
的资源竞争和死锁问题。

这个问题的描述是:五位哲学家围坐在一张圆桌前,每位哲学家面前有一碗意面,但他们之间共享一把只能被一个人同时使用的餐叉。

每位哲学家需要先拿起右手边的餐叉,再拿起左手边的餐叉才能吃饭,吃完后放下餐叉继续思考问题。

如果哲学家之间同时试图拿起自己左右手边的餐叉,就会导致死锁问题,无法继续进餐。

这个问题的趣味例子在于通过这种抽象的场景,展现了并发编程中常见的竞争
和死锁问题。

实际上,哲学家进餐问题也可以被看作是对资源管理和同步机制的一种考验。

如果每位哲学家都按照固定的顺序拿餐叉,就不会发生死锁;而如果哲学家们都随机地尝试拿餐叉,就可能会出现资源竞争的问题,导致无法进餐。

这个问题的趣味之处在于,通过一个简单的场景,展示了复杂的并发编程中可
能出现的问题,让人们更加深入地理解并发编程中的挑战和技巧。

通过哲学家进餐问题的讨论,人们可以思考如何设计合理的同步机制和资源管理策略,避免竞争和死锁问题的发生,提高程序的并发性能和稳定性。

总的来说,哲学家进餐问题是一个充满趣味和启发的例子,能够帮助人们更好
地理解并发编程中的难点,同时也能够激发人们对于解决问题的创造力和思考能力。

通过这个例子的讨论,人们可以不仅仅学到技术知识,更能够培养出解决问题的能力和思维方式,为未来的学习和工作打下坚实的基础。

愿每位哲学家都能够顺利进餐,思考问题,探索未知的世界。

操作系统哲学家进餐问题

操作系统哲学家进餐问题

操作系统实习报告一、设计目的:死锁是进程并发执行过程中可能出现的现象,所谓死锁,是指多个进程在运行过程中因争夺资源而造成的一种僵局。

哲学家就餐问题是描述死锁的经典例子。

为了防止死锁,可以采用资源预分配法或者资源按序分配法。

资源预分配法是指进程在运行前一次性地向系统申请它所需要的全部资源,如果系统当前不能够满足进程的全部资源请求,则不分配资源, 此进程暂不投入运行,如果系统当前能够满足进程的全部资源请求, 则一次性地将所申请的资源全部分配给申请进程。

二、设计内容哲学家进餐问题的模拟。

三、开发环境windows环境,Myeclipse平台。

四、分析设计<一>实验原理哲学家进餐问题描述的是五个哲学家共用一张圆桌,分别坐在周围的五张椅子上,在圆桌上有五只碗和五只筷子。

他们的生活方式是交替地进行思考和进餐。

平时,一个哲学家进行思考,饥饿时便试图取用其左右的最靠近他的筷子,只有在他拿到两只筷子时才能进餐。

进餐完毕放下筷子继续思考。

由于:①只有拿到两只筷子时,哲学家才能吃饭;②如果筷子已经在他人手上,则该哲学家必须等到他人吃完之后才能拿到筷子;③任何一个哲学家在自己没有拿到两只筷子吃饭之前,决不放下自己手中的筷子。

则可能出现五个哲学家都饥饿时都拿着一直筷子。

这样就可能五个哲学家都用不上餐。

该问题可用记录型信号量解决,经分析可知,放在桌子上的筷子是临界资源,在一段时间内只允许一位哲学家使用,为了实现对筷子的互斥使用,可以用一个信号量表示一只筷子,由这五个信号量组成信号量数组。

当哲学家饥饿时总是先拿其左边的筷子,成功后,再去拿右边的筷子,又成功后方可就餐。

进餐完,又先放下他左边的筷子,再放下右边筷子。

这个算法可以保证不会有两个相邻的哲学家同时就餐,但有可能引起死锁。

对于死锁问题可采取这样的几种解决方法:(1)至多只允许四个哲学家同时进餐,以保证至少有一个哲学家可以进餐,最终总会释放出他所用过的两只筷子,从而可使更多的哲学家进餐;(2)仅当左右两只筷子均可用时,才允许哲学家拿起筷子就餐(3)规定奇数号哲学家先拿起右边筷子,然后再去拿左边筷子,而偶数号哲学家则相反。

哲学家问题解决死锁的方法(一)

哲学家问题解决死锁的方法(一)

哲学家问题解决死锁的方法(一)哲学家问题解决死锁引言哲学家问题是一个典型的并发编程问题,它涉及到五位哲学家围坐在一张圆桌旁,每人面前有一盘饭和一只叉子。

哲学家的生活有两种状态:思考和进餐。

每个哲学家进餐时需要两只叉子,但是一次只能拿起一只,在他左右两边的哲学家也需要使用叉子。

这个问题的挑战在于如何避免死锁的发生。

方法一:使用死锁避免算法使用死锁避免算法是一种解决哲学家问题的常见方法。

该算法的基本思想是通过限制某些哲学家的进餐行为,以避免产生死锁。

1.限制偶数编号的哲学家先拿左手边的叉子,再拿右手边的叉子。

2.限制奇数编号的哲学家先拿右手边的叉子,再拿左手边的叉子。

3.对于哲学家的进餐过程,需要先检查叉子的可用性,如果叉子被其他哲学家使用,则等待。

方法二:使用资源分级策略资源分级策略是另一种解决哲学家问题的方法,它通过划分资源的优先级来避免死锁的发生。

1.将五只叉子按照优先级从高到低排序。

2.每个哲学家在进餐前需要先请求相应优先级的叉子。

3.偶数编号的哲学家优先请求左手边的叉子,再请求右手边的叉子。

4.奇数编号的哲学家优先请求右手边的叉子,再请求左手边的叉子。

方法三:使用资源分配策略资源分配策略是一种更加灵活的解决哲学家问题的方法,它通过动态分配资源来避免死锁。

1.创建一个共享的资源管理器,用于管理叉子的分配和释放。

2.每个哲学家在进餐前向资源管理器请求两只叉子。

3.资源管理器根据当前可用的叉子数量进行分配。

4.当一个哲学家进餐结束后,释放叉子,并通知资源管理器。

结论哲学家问题是一个复杂的并发编程问题,需要谨慎设计解决方案以避免死锁的发生。

通过使用死锁避免算法、资源分级策略和资源分配策略等方法,可以有效地解决哲学家问题,并保证系统的稳定性和高效性。

在实际应用中,可以根据具体需求选择适合的方法来解决死锁问题。

哲学家问题解决方法

哲学家问题解决方法

哲学家问题解决方法
哲学家问题是一个经典的并发编程问题,旨在解决多个哲学家共享有限资源
(如餐桌上的筷子)时可能发生的死锁情况。

在这个问题中,哲学家们围坐在一张圆桌旁,每个哲学家面前都有一只餐具桌子上有一定数量的筷子,而每个哲学家需要同时拿到两只筷子才能进食。

如果每个哲学家都试图先拿起同一边的筷子,那么就会造成死锁,导致每个哲学家都无法进食。

针对哲学家问题,有几种解决方法如下:
1.资源分级:通过给每个筷子分配唯一的编号,并规定哲学家只能按照编号递
增的顺序拿起筷子,可以有效避免死锁的出现。

在这种方法中,第一个哲学家先尝试拿起编号较小的筷子,如果成功则继续拿起编号较大的筷子,否则放下已拿起的筷子并等待。

其他哲学家按照相同顺序进行操作。

2.资源互斥:使用互斥锁(mutex)来确保同时只有一个哲学家能够拿起一对
筷子。

当一个哲学家准备进食时,他必须先尝试获得左边的筷子,如果成功则再尝试获得右边的筷子,反之则释放已拿起的筷子。

这种方法可以避免死锁情况的发生。

3.资源剥夺:在一段时间内限制某个哲学家可以进食的次数,使得其他哲学家
有机会获得筷子进食。

例如,当一个哲学家成功拿起筷子后,可以设置一个计时器,在超过一定时间未释放筷子时,系统强制将筷子夺取回来让其他哲学家使用。

这种方法可以避免某个哲学家长时间占用筷子,导致其他哲学家无法进食的情况。

总之,针对哲学家问题的解决方法主要包括资源分级、资源互斥和资源剥夺。

通过合理的设计和策略,我们可以解决哲学家问题,确保哲学家们能够公平地共享资源,避免死锁的发生。

实验一 哲学家就餐问题

实验一 哲学家就餐问题

实验一哲学家就餐问题一、实验目的1.熟练使用VC++6.0编译环境,调试并正确运行程序。

2.熟悉哲学家就餐问题流程。

3.理解哲学家就餐问题中出现的问题,进而掌握死锁的必要条件。

4.熟悉源程序中产生和防止死锁的算法,及其相关窗口操作。

二、实验原理1.问题描述:有五个哲学家围坐在一圆桌旁,桌中央有一盘通心粉,每人面前有一只空盘子,每两人之间放一只筷子,每个哲学家的行为时思考,饥饿,然后吃通心粉,每个哲学家必须拿到两只筷子,并且每个人只能直接从自己的左边或右边取筷子。

2.防止死锁发生的分配方式:仅当一个哲学家左右两边的筷子都可用时,才允许他拿筷子。

这样要么一次占有两只筷子(所有线程需要的资源)进行下一步吃通心粉,然后释放所有的资源;要么不占用资源,这样就不可能产生死锁了。

3.产生死锁的分配方式:当筷子(资源)可用时,先分配左边的筷子,等待一会后再分配右边的筷子,由于这个过程中,左边的筷子一直没有释放,就可能产生死锁了。

4.程序运行说明:程序运行过程中会弹出一个MessageBox提示操作者操作:1)第一个对话框用于选择运行模式a.选择yes表示采用的是运行的防止死锁的方式,这样的话整个程序可以一直运行下去,不会产生死锁。

b.选择no表示运行产生死锁的方式会弹出第二个对话框。

2)第二个对话框用于选择运行时,线程运行的时间a.选择yes线程时间比较短,很快就可以死锁。

b.选择no线程时间跟选择yes时的时间差不多,产生死锁的时间稍微长一点。

三、实验过程及分析1.PhilosopherThread(LPVOID pVoid)函数伪代码1)不死锁方式Var mutexleftchopstick,mutexrightchopstick;Beging:Resting;Waiting;P{mutexleftchopstick};P{mutexrightchopstick};GetResource{leftchopstick,rightchopstick};Eating;V{mutexleftchopstick};V{mutexrightchopstick};End2)发生死锁方式Var mutexleftchopstick,mutexrightchopstick;Beging:Resting;Waiting;P{mutexleftchopstick};GetResource{leftchopstick};P{mutexrightchopstick};GetResource{rightchopstick};Eating;V{mutexleftchopstick};V{mutexrightchopstick};End2.代码分析1)不发生死锁时,哲学家迅速同时抢占两个筷子的资源,而若是不能同时抢占两只筷子则继续等待,知道有两只筷子空闲则抢占,这样就打破了死锁的必要条件。

计算机操作系统哲学家进餐问题的教学探讨

计算机操作系统哲学家进餐问题的教学探讨

计算机操作系统哲学家进餐问题的教学探讨
计算机操作系统哲学家进餐问题是一个经典的模拟问题,用于帮助学生理解线程同步、死锁和资源管理等操作系统的核心概念。

该问题描述了n个哲学家围坐在一张圆桌周围,每个哲学家面前有一盘食物,中间有n个筷子。

哲学家需要吃饭,但是每个哲学家只能使用自己左右两边的筷子来进餐。

如果哲学家发现左边或右边的筷子被占用,就会等待,直到筷子被释放。

这个问题中存在死锁的可能性。

在教学中,可以通过演示代码或编写代码来模拟这个问题的运行情况,帮助学生理解这些概念的实际应用。

例如,可以演示如何使用锁和条件变量来解决死锁问题,或者如何
使用信号量管理系统资源来避免死锁问题。

另外可以讨论不同的算法和策略,如顺序获取筷子,随机获取筷子等,来说明如何避免死锁的发生.
总之,通过这个问题的模拟,学生可以加深对操作系统的理解,并且对如何解决多线程并发问题有更深入的了解。

在教学探讨中,老师可以通过不同的模拟实验来说明线程同步和死锁的本质原理以及如何避免和解决这些问题。

鼓励学生进行自己的实验和探究,以加深对这些概念的理解。

关于哲学家就餐问题的分析代码.

关于哲学家就餐问题的分析代码.

关于哲学家就餐问题的分析代码.①总体思路: 都去拿左边的筷⼦,并且最后⼀个⼈不能去拿筷⼦(防⽌⼤家都拿了左边的筷⼦,没有右边的筷⼦,导致死锁了),解决死锁问题的办法就是同时只允许四位哲学家同时拿起同⼀边的筷⼦,这样就能保证⼀定会有⼀位哲学家能够拿起两根筷⼦完成进⾷并释放资源,供其他哲学家使⽤,从⽽实现永动,避免了死锁。

举个最简单的栗⼦,假定0~3号哲学家已经拿起了他左边的筷⼦,然后当4号哲学家企图去拿他左边的筷⼦的时候,将该哲学家的线程锁住,使其拿不到其左边的筷⼦,然后其左边的筷⼦就可以被3号哲学家拿到,然后3号哲学家进餐,释放筷⼦,然后更多的哲学家拿到筷⼦并进餐。

如何才能实现当4号哲学家企图拿起其左边的筷⼦的时候将该哲学家的线程阻塞?这个时候就要⽤到该问题的提出者迪杰斯特拉(这货还提出了迪杰斯特拉最短路径算法,著名的银⾏家算法也是他发明的)提出的信号量机制。

因为同时只允许有四位哲学家同时拿起左筷⼦,因此我们可以设置⼀个信号量r,使其初始值为4,然后每当⼀位哲学家企图去拿起他左边的筷⼦的时候,先对信号量做⼀次P操作,从⽽当第五位哲学家企图去拿做筷⼦的时候,对r做⼀次P操作,r = -1,由r < 0得第五位哲学家的线程被阻塞,从⽽不能拿起左筷⼦,因此也就避免了死锁问题。

然后当哲学家放下他左边的筷⼦的时候,就对r做⼀次V操作。

②在主线程和⼦线程中,避免了竞争关系.代码参考如下:/************************************ @file linux_zexuejia.c* @copyright ⽉光下的脚步 Co.,Ltd.ALL Right Reserved* @brief 使⽤信号量和互斥锁完成,哲学家就餐问题。

* @author 王有康* @data 2019、7、31* @version V1.1* @Last Modified 2018/10/25 wangyoukang* @note 当前版本是v1.1版本,以后需要修改,可以在上添加版本和修改⽇期* @note* @warning* @Function List :************************************/#include <stdio.h>#include <stdlib.h>#include <malloc.h>#include <time.h>#include <unistd.h>#include <pthread.h>#include <semaphore.h>#define N 5//互斥锁pthread_mutex_t chops[N];//信号量sem_t r;/*********************** @fn philosopher* @biref 每次只有4个⼈能够获得左⼿资源,这样不会死锁* @param philosopher number* @return* @other***********************/void philosopher(void *arg){int i = *(int *)arg;int left = i;int right = (i + 1)%N;while(1){printf("哲学家%d在思考问题\n",i);usleep(1000);printf("哲学家%d饿了\n",i);sem_wait(&r);pthread_mutex_lock(&chops[left]);printf("philosopher %d take left lock\n",i);pthread_mutex_lock(&chops[right]);printf("philosopher %d take right lock\n",i);printf("philosopher %d eat\n",i);usleep(1000);pthread_mutex_unlock(&chops[right]);printf("philosopher %d release right lock\n",i);pthread_mutex_unlock(&chops[left]);printf("philosopher %d realease left lock\n",i);sem_post(&r);}}/*********************** @fn philosopher* @biref 主函数* @param* @return* @other***********************/int main(int argc,char **argv){int i = 0,*ptr;pthread_t tid[N];for(i = 0;i < N;i++){pthread_mutex_init(&chops[i],NULL);}sem_init(&r,0,4);for(i = 0;i < N;i++){//防⽌主线程和对等线程竞争,给线程和主线程分配不同的内存区域。

死锁—哲学家吃饭问题

死锁—哲学家吃饭问题

死锁—哲学家吃饭问题由于线程能被阻塞,更由于synchronized方法能阻止其它线程访问本对象,因此有可能会出现如下这种情况:线程一在等线程二(释放某个对象),线程二又在等线程三,这样依次排下去直到有个线程在等线程一。

这样就形成了一个环,每个线程都在等对方释放资源,而它们谁都不能运行。

这就是所谓的死锁(deadlock)。

如果程序一运行就死锁,那倒也简单了。

你可以马上着手解决这个问题。

但真正的麻烦在于,程序看上去能正常运行,但是却潜伏着会引起死锁的隐患。

或许你认为这里根本就不可能会有死锁,而bug 也就这样潜伏下来了。

直到有一天,让某个用户给撞上了(而且这种bug还很可能是不可重复的)。

所以对并发编程来说,防止死锁是设计阶段的一个重要任务。

下面我们来看看由Dijkstra发现的经典的死锁场景:哲学家吃饭问题。

原版的故事里有五个哲学家(不过我们的例程里允许有任意数量)。

这些哲学家们只做两件事,思考和吃饭。

他们思考的时候,不需要任何共享资源,但是吃饭的时候,就必须坐到餐桌旁。

餐桌上的餐具是有限的。

原版的故事里,餐具是叉子,吃饭的时候要用两把叉子把面条从碗里捞出来。

但是很明显,把叉子换成筷子会更合理,所以:一个哲学家需要两根筷子才能吃饭。

现在引入问题的关键:这些哲学家很穷,只买得起五根筷子。

他们坐成一圈,两个人的中间放一根筷子。

哲学家吃饭的时候必须同时得到左手边和右手边的筷子。

如果他身边的任何一位正在使用筷子,那他只有等着。

这个问题之所以有趣就在于,它演示了这么一个程序,它看上去似乎能正常运行,但是却容易引起死锁。

你可以自己试试,用命令行参数调节哲学家的数量和思考的时间。

如果有很多哲学家,而且/或者他们思考的时间很长,或许你永远也碰不到死锁,但是死锁的可能性总还是在的。

默认的命令行参数会让它很快地死锁://: c13:DiningPhilosophers.java// Demonstrates how deadlock can be hidden in a program.// {Args: 5 0 deadlock 4}import java.util.*;class Chopstick {private static int counter = 0;private int number = counter++;public String toString() {return"Chopstick " + number;}}class Philosopher extends Thread {private static Random rand = new Random();private static int counter = 0;private int number = counter++;private Chopstick leftChopstick;private Chopstick rightChopstick;static int ponder = 0; // Package accesspublic Philosopher(Chopstick left, Chopstick right) {leftChopstick = left;rightChopstick = right;start();}public void think() {System.out.println(this + " thinking");if(ponder > 0)try {sleep(rand.nextInt(ponder));} catch(InterruptedException e) {throw new RuntimeException(e);}}public void eat() {synchronized(leftChopstick) {System.out.println(this + " has "+ this.leftChopstick + " Waiting for "+ this.rightChopstick);synchronized(rightChopstick) {System.out.println(this + " eating");}}}public String toString() {return"Philosopher " + number;}public void run() {while(true) {think();eat();}}}public class DiningPhilosophers {public static void main(String[] args) {if(args.length < 3) {System.err.println("usage:\n" +"java DiningPhilosophers numberOfPhilosophers " +"ponderFactor deadlock timeout\n" +"A nonzero ponderFactor will generate a random " +"sleep time during think().\n" +"If deadlock is not the string " +"'deadlock', the program will not deadlock.\n" +"A nonzero timeout will stop the program after " +"that number of seconds.");System.exit(1);}Philosopher[] philosopher =new Philosopher[Integer.parseInt(args[0])];Philosopher.ponder = Integer.parseInt(args[1]);Chopstickleft = new Chopstick(),right = new Chopstick(),first = left;int i = 0;while(i < philosopher.length - 1) {philosopher[i++] =new Philosopher(left, right);left = right;right = new Chopstick();}if(args[2].equals("deadlock"))philosopher[i] = new Philosopher(left, first);else// Swapping values prevents deadlock:philosopher[i] = new Philosopher(first, left);// Optionally break out of program:if(args.length >= 4) {int delay = Integer.parseInt(args[3]);if(delay != 0)new Timeout(delay * 1000, "Timed out");}}} ///:~Chopstick和Philosopher都包含一个能自动递增的static counter。

哲学家进餐问题

哲学家进餐问题

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

约束条件(1)只有拿到两只筷子时,哲学家才能吃饭。

(2)如果筷子已被别人拿走,则必须等别人吃完之后才能拿到筷子。

(3)任一哲学家在自己未拿到两只筷子吃完饭前,不会放下手中已经拿到的筷子。

2.求解方法(1).信号量的设置放在桌子上的筷子是临界资源,在一段时间内只允许一位哲学家使用,为了实现对筷子的互斥访问,可以用一个信号量表示筷子,由这五个信号量构成信号量数组。

semaphore chopstick[5] = {1,1,1,1,1};while(true){/*当哲学家饥饿时,总是先拿左边的筷子,再拿右边的筷子*/wait(chopstick[i]);wait(chopstick[(i+1)%5]);// 吃饭/*当哲学家进餐完成后,总是先放下左边的筷子,再放下右边的筷子*/signal(chopstick[i]);signal(chopstick[(i+1)%5]);}上述的代码可以保证不会有两个相邻的哲学家同时进餐,但却可能引起死锁的情况。

假如五位哲学家同时饥饿而都拿起的左边的筷子,就会使五个信号量chopstick都为0,当他们试图去拿右手边的筷子时,都将无筷子而陷入无限期的等待。

(2)避免死锁策略一原理:至多只允许四个哲学家同时进餐,以保证至少有一个哲学家能够进餐,最终总会释放出他所使用过的两支筷子,从而可使更多的哲学家进餐。

定义信号量count,只允许4个哲学家同时进餐,这样就能保证至少有一个哲学家可以就餐。

semaphore chopstick[5]={1,1,1,1,1};semaphore count=4; // 设置一个count,最多有四个哲学家可以进来void philosopher(int i){while(true){think();wait(count); //请求进入房间进餐 当count为0时 不能允许哲学家再进来了wait(chopstick[i]); //请求左手边的筷子wait(chopstick[(i+1)%5]); //请求右手边的筷子eat();signal(chopstick[i]); //释放左手边的筷子signal(chopstick[(i+1)%5]); //释放右手边的筷子signal(count); //退出房间释放信号量}}策略二原理:仅当哲学家的左右两支筷子都可用时,才允许他拿起筷子进餐。

哲学家进餐问题-3中解决方案

哲学家进餐问题-3中解决方案

哲学家进餐问题-3中解决⽅案问题描述⼀张圆桌上坐着5名哲学家,每两个哲学家之间的桌上摆⼀根筷⼦,桌⼦的中间是⼀碗⽶饭,如图2-10所⽰。

哲学家们倾注毕⽣精⼒⽤于思考和进餐,哲学家在思考时,并不影响他⼈。

只有当哲学家饥饿的时候,才试图拿起左、右两根筷⼦(⼀根⼀根地拿起)。

如果筷⼦已在他⼈⼿上,则需等待。

饥饿的哲学家只有同时拿到了两根筷⼦才可以开始进餐,当进餐完毕后,放下筷⼦继续思考。

问题分析1) 关系分析。

5名哲学家与左右邻居对其中间筷⼦的访问是互斥关系。

2) 整理思路。

显然这⾥有五个进程。

本题的关键是如何让⼀个哲学家拿到左右两个筷⼦⽽不造成死锁或者饥饿现象。

那么解决⽅法有两个,⼀个是让他们同时拿两个筷⼦;⼆是对每个哲学家的动作制定规则,避免饥饿或者死锁现象的发⽣。

⼀共5个哲学家,编号0 ~4, 5⽀筷⼦编号也是0 ~4, 0号哲学家右⼿的筷⼦编号是0号,逆时针增加,哲学家的编号也是逆时针增加所以:0号哲学家对应的是: 4号和1号筷⼦.1号哲学家对应的是: 0号和2号筷⼦.2号哲学家对应的是: 1号和3号筷⼦.3号哲学家对应的是: 2号和4号筷⼦.4号哲学家对应的是: 3号和0号筷⼦.所以有宏定义:#define left(phi_id) (phi_id+N-1)%N#define right(phi_id) (phi_id+1)%NN = 55⽀筷⼦对应5个互斥锁,所以:pthread_mutex_t forks[N]={PTHREAD_MUTEX_INITIALIZER};哲学家线程需要执⾏的动作是:void take_forks(int id){//获取左右两边的筷⼦printf("Pil[%d], left[%d], right[%d]\n", id, left(id), right(id));pthread_mutex_lock(&forks[left(id)]);pthread_mutex_lock(&forks[right(id)]);//printf("philosopher[%d] take_forks...\n", id);}void put_down_forks(int id){printf("philosopher[%d] is put_down_forks...\n", id);pthread_mutex_unlock(&forks[left(id)]);pthread_mutex_unlock(&forks[right(id)]);}void* philosopher_work(void *arg){int id = *(int*)arg;printf("philosopher init [%d] \n", id);while(1){thinking(id);take_forks(id);eating(id);put_down_forks(id);}}该算法存在以下问题:当五个哲学家都想要进餐,分别拿起他们左边筷⼦的时候(都恰好执⾏完pthread_mutex_unlock(&forks[left(id)]);)筷⼦已经被拿光了,等到他们再想拿右边的筷⼦的时候(执⾏pthread_mutex_unlock(&forks[right(id)]);)就全被阻塞了,这就出现了死锁。

哲学家进餐问题和银行家算法

哲学家进餐问题和银行家算法

哲学家进餐问题和银行家算法是操作系统中的经典问题,都涉及到资源分配和死锁的问题。

哲学家进餐问题是关于死锁的经典问题。

假设有五位哲学家坐在一张圆桌周围,他们轮流思考和吃饭。

吃饭的时候,他们需要使用两边的筷子。

问题是,如果哲学家们在拿起左边的筷子之前必须等待右边的筷子可用,那么有可能发生死锁。

例如,如果每个哲学家都拿起左边的筷子并等待右边的筷子,那么就会出现循环等待的情况,导致所有人都饿死,这就是死锁。

为了避免这种情况,操作系统需要一种机制来避免死锁,比如规定哲学家们必须按照固定的顺序拿起筷子等。

银行家算法是关于资源分配和避免死锁的算法。

该算法模拟了银行贷款的场景,通过检查请求是否会导致死锁来决定是否分配资源。

如果分配资源会导致死锁,算法就会拒绝该请求;否则,它就会分配资源。

银行家算法需要在操作系统中进行配置,以便动态管理资源的分配,并在需要时回收资源以避免死锁。

这两个问题的解决方法是操作系统中的重要组成部分,旨在确保系统中的多个进程或线程能够公平地共享资源,并避免出现死锁等不期望的情况。

操作系统实验报告哲学家就餐

操作系统实验报告哲学家就餐

操作系统实验报告哲学家就餐一、实验目的:通过模拟哲学家就餐问题,了解并掌握操作系统中的进程同步机制,以及解决进程间资源竞争所引发的死锁问题。

二、实验介绍:哲学家就餐问题是由荷兰计算机科学家伊克斯特拉(Dijkstra)于1965年首次提出的。

其问题描述如下:五位哲学家坐在一张圆桌子周围,每个哲学家面前有一碗饭和一根筷子。

哲学家的生活方式是交替地进行思考和进食。

当一个哲学家思考时,他不需要使用他的两个筷子;当一个哲学家想吃饭时,他需要同时获取他的左右两个筷子,并在获取到筷子后才能开始进食。

问题的关键是如何解决哲学家间的筷子竞争问题,以及避免死锁的发生。

三、实验设计:1.并发思路每个哲学家作为一个进程,在进行思考和进食这两个操作之前,需要获取他的两个筷子。

接下来考虑进程同步的两个关键点:-互斥:保证每个筷子同时只能被一个哲学家使用,避免资源竞争问题。

-死锁避免:通过限制只允许至多四位哲学家同时持有筷子,从而避免死锁发生。

2.进程同步机制- 互斥:使用Semaphore实现互斥,每个筷子都是一个Semaphore,初始值为1-死锁避免:引入一个全局计数器,记录当前持有筷子的哲学家数量,每次哲学家想要获取筷子时,先检查该计数器,仅当计数器小于4时才会获取筷子。

四、实验步骤:1.创建5个哲学家进程和5个筷子线程。

2.每个哲学家的线程循环执行思考和进食操作。

3.在进食之前,哲学家需要获取两个筷子,获取筷子的顺序按照哲学家编号进行,每个哲学家先获取自己的左边筷子,再获取自己的右边筷子。

4.进行进食操作后,哲学家释放两个筷子。

5.循环执行步骤3和步骤4,直到实验结束。

五、实验结果:通过观察实验结果,可以看到哲学家的思考和进食操作交替进行,并且避免了死锁的发生。

六、实验总结:通过本次实验,我了解了操作系统中的进程同步机制,并学会了如何解决资源竞争和死锁问题。

在本实验中,我使用了Semaphore和全局计数器实现了互斥和死锁避免,从而成功模拟了哲学家就餐问题。

哲学家就餐问题解决死锁的三种思路

哲学家就餐问题解决死锁的三种思路

哲学家就餐问题是计算机科学中一个经典的同步问题,它描述了五位哲学家围坐在圆桌前就餐,每位哲学家必须先拿起右边的餐具再拿起左边的餐具,但每次只能有一位哲学家拿起餐具就餐。

这个问题的关键在于如何避免死锁,即所有哲学家都拿起了右边的餐具,然后等待拿左边餐具的哲学家放下右边的餐具。

为了解决这个问题,计算机科学家提出了三种思路。

第一种思路是引入一个“服务生”,服务生负责给哲学家提供餐具,每次只允许一个哲学家向服务生请求餐具,这样就可以避免死锁。

然而,这种方法可能会引入新的竞争条件,服务生可能会成为新的瓶颈,从而降低系统的效率。

第二种思路是引入资源分级,为了避免死锁,可以给每个哲学家的餐具加上编号,要求哲学家先拿编号较小的餐具,再拿编号较大的餐具。

这样就可以避免死锁,但是可能会增加系统的复杂性,需要管理更多的资源状态。

第三种思路是破坏死锁的四个必要条件之一。

死锁发生的四个必要条件分别是互斥、请求并持有、不可剥夺和循环等待。

为了避免死锁,可以破坏其中一个或多个条件。

可以引入超时机制,当哲学家拿到一个餐具后,一定时间内没有获得另一个餐具,就放下手中的餐具,避免形成循环等待。

这种方法可以在不增加系统复杂性的情况下有效地解决死锁问题。

在我看来,这三种思路各有优缺点,要根据具体的场景和需求选择合适的方法。

不同的问题可能需要采用不同的思路来解决,需要权衡各种因素来做出最佳的决策。

哲学家就餐问题是一个充满哲学思考的经典问题,它不仅考察了计算机科学中的同步与互斥问题,更可以引发我们对于资源分配、竞争条件和系统设计的深入思考。

通过对哲学家就餐问题的深入理解,我们可以更加灵活地运用不同的思路解决实际中的问题,让我们的系统更加健壮和高效。

结语:通过对哲学家就餐问题的深入探讨,我们可以发现在计算机科学中,解决死锁问题有很多种思路,每种思路都有其独特的优缺点。

只有充分理解这些思路并根据具体情况做出权衡,才能更好地解决实际中遇到的死锁问题。

哲学家就餐问题的算法实现

哲学家就餐问题的算法实现

哲学家就餐问题的算法实现哲学家就餐问题是一个经典的并发计算问题,描述了五个哲学家围坐在一张圆桌前,每个人面前有一碟食物,并且每两个哲学家之间共享一只叉子。

每个哲学家可以执行两个操作:思考和就餐。

当一个哲学家就餐时,他需要同时拿起他的左右两只叉子,并且在就餐完毕后放下叉子。

这个问题的难点在于如何解决可能出现的死锁情况,即每个哲学家都拿起了自己左边的叉子,然后都在等待右边的叉子。

为了避免死锁,需要设计一个算法来保证每个哲学家都能够正确地就餐。

以下是一个可能的解决方案,称为"资源分级"算法:1. 为每个哲学家设计一个状态变量,并初始化为"思考"状态。

2. 每个叉子也有一个状态变量,初始状态为"可用"。

3. 当一个哲学家想要就餐时,他必须拿起他的左右两只叉子。

但是如果有一只或两只叉子已经被其他哲学家持有,他必须等待。

4. 当一个哲学家拿起了他的左右两只叉子时,他可以开始就餐,并将状态变量更新为"就餐"状态。

5. 当一个哲学家就餐完毕后,他将叉子放回桌子上,并将状态变量更新为"思考"状态。

6. 如果一个哲学家发现无法同时拿到他的左右两只叉子,他需要先放下已经持有的叉子,并将状态变量更新为"等待"状态。

然后他等待其他哲学家释放叉子的资源,并尝试再次拿起他的左右两只叉子。

以上是一个简单的"资源分级"算法,可以避免死锁的发生。

但是这个算法可能会导致一些哲学家始终处于等待状态,无法实现公平性。

为了解决这个问题,可以使用更复杂的算法,如Chandy/Misra解法或Dijkstra解法,这些算法可以实现更公平的资源分配。

总结起来,哲学家就餐问题是一个经典的并发计算问题,可能会引发死锁情况。

通过设计合理的算法,如"资源分级"算法或更复杂的解法,可以解决这个问题并保证公平性。

哲学家就餐问题(进程管理)

哲学家就餐问题(进程管理)

进程管理一、设计目的、功能与要求设计目的:掌握进程管理的相关内容,对进程的同步和互斥,及信号量机制有深入的理解实验内容:模拟实现用信号量机制解决哲学家就餐问题具体要求:任选一种计算机高级语言编程实现实现5个哲学家(5只筷子)的顺利就餐需避免出现死锁使用信号量、及信号量的等待队列使用P操作、V操作能够显示每个哲学家、及每只筷子的状态二、问题的详细描述、需求分析该实验要求模拟实现用信号量机制解决哲学家就餐问题。

哲学家就餐问题详细描述如下:有五个哲学家围坐在一圆桌旁,桌中央有一盘通心粉,每人面前有一只空盘子,有五个哲学家围坐在一圆桌旁,桌中央有一盘通心粉,每人面前有一只空盘子,每两人之间放一只筷子,即共5只筷子。

每个哲学家的行为是思考和进餐。

每个哲学家的行为是思考和进餐。

为了进餐,每个哲学家必须拿到两只筷子,并且每个人只能直接从自己的左边或右边去取筷子。

思考时则同时将两支筷子放回原处时则同时将两支筷子放回原处。

规则:只有拿到两只筷子时,哲学家才能吃饭;只有拿到两只筷子时,哲学家才能吃饭;如果筷子已经在他人手上,则该哲学家必须等到他人吃完之后才能拿到筷子;如果筷子已经在他人手上,则该哲学家必须等到他人吃完之后才能拿到筷子;任何一个哲学家在自己没有拿到两只筷子吃饭之前,决不放下自己手中的筷子。

为了解决哲学家就餐问题同时解决死锁现象,需要设计一定的解决策略。

有这样几种解决办法:1.至多只允许四个哲学家同时进餐,以保证至少有一个哲学家可以进餐,最终总会释放出他所用过的两只筷子,从而可使更多的哲学家进餐;2.仅当左右两只筷子均可用时,才允许哲学家拿起筷子就餐;3.规定奇数号哲学家先拿起右边筷子,然后再去拿左边筷子,而偶数号哲学家则相反。

该实验我采取了第2种解决方案,每个哲学家在确定自己左右两边的筷子都能用时,才能同时拿起两只筷子进餐,进餐完成后同时放下两只筷子。

三、数据结构、功能设计(功能与框图、功能模块说明)该实验使用java的多线程,同时利用到关键字synchronized实现了共享数据的互斥锁定,以保证每只筷子的状态的互斥的。

哲学家就餐问题解决死锁的三种思路

哲学家就餐问题解决死锁的三种思路

哲学家就餐问题解决死锁的三种思路哲学家就餐问题解决死锁的三种思路一、引言哲学家就餐问题是计算机科学中一个经典的并发算法问题,其旨在通过模拟哲学家进餐的过程来展示并发编程中可能出现的死锁情况及解决方法。

在这个问题中,有五个哲学家坐在一张圆形桌子周围,每个哲学家有自己的饭碗和叉子。

他们的生活习惯是交替思考和进餐:当一个哲学家思考时,他将放下叉子,尝试从左右两边的邻居那里得到两个叉子以进行用餐;当一个哲学家吃饭时,他会用完两个叉子,然后放下叉子并继续思考。

问题的关键是如何避免哲学家之间发生死锁,即每个哲学家都拿起了自己右边的叉子,而没有一个人能拿到他左边的叉子。

本文将介绍三种解决死锁问题的思路。

二、解决思路一:资源分级资源分级的思路是将叉子进行分级,例如将五个叉子从1到5进行编号。

对于每个哲学家,他必须先尝试获得数字较小的叉子,然后才能尝试获取数字较大的叉子。

这样做的目的是避免所有哲学家同时尝试获取同一个叉子,从而导致死锁的发生。

当一个哲学家需要进餐时,他必须先获取编号较小的叉子,然后尝试获取编号较大的叉子。

如果他无法获取到编号较小的叉子,他就会放下已经获取的叉子,并释放已经占用的资源。

这样,其他哲学家就有机会获取叉子继续进餐。

这种思路可以有效地解决死锁问题。

三、解决思路二:资源分配顺序资源分配顺序的思路是约定哲学家获取叉子的顺序。

在这种思路中,我们可以为每个哲学家分配一个固定的顺序,例如从1到5。

按照这个顺序,哲学家们必须按照排列顺序尝试获取叉子。

当一个哲学家需要进餐时,他会按照规定的顺序尝试获取叉子。

如果他无法获取到所需的叉子,他就会放下已经获取的叉子,并释放已经占用的资源。

这样,其他哲学家就有机会获取叉子继续进餐。

通过约定获取资源的顺序,我们可以避免死锁的发生。

四、解决思路三:资源剥夺法资源剥夺法的思路是当一个哲学家尝试获取叉子时,如果他无法获取到所需的叉子,他将放下已经获取的叉子并等待一段时间后重试。

利用记录型信号量解决不会出现死锁的哲学家就餐问题

利用记录型信号量解决不会出现死锁的哲学家就餐问题

利⽤记录型信号量解决不会出现死锁的哲学家就餐问题试利⽤记录性信号量写出⼀个不会出现死锁的哲学家进餐问题的算法规定在拿到左侧的筷⼦后,先检查右⾯的筷⼦是否可⽤。

如果不可⽤,则先放下左侧筷⼦,等⼀段时间再重复整个过程。

分析:当出现以下情形,在某⼀个瞬间,所有的哲学家都同时启动这个算法,拿起左侧的筷⼦,⽽看到右侧筷⼦不可⽤,⼜都放下左侧筷⼦,等⼀会⼉,⼜同时拿起左侧筷⼦……如此这样永远重复下去。

对于这种情况,所有的程序都在运⾏,但却⽆法取得进展,即出现饥饿,所有的哲学家都吃不上饭。

(2) 描述⼀种没有⼈饿死(永远拿不到筷⼦)算法。

考虑了四种实现的⽅式(A、B、C、D):A.原理:⾄多只允许四个哲学家同时进餐,以保证⾄少有⼀个哲学家能够进餐,最终总会释放出他所使⽤过的两⽀筷⼦,从⽽可使更多的哲学家进餐。

以下将room 作为信号量,只允许4 个哲学家同时进⼊餐厅就餐,这样就能保证⾄少有⼀个哲学家可以就餐,⽽申请进⼊餐厅的哲学家进⼊room 的等待队列,根据FIFO 的原则,总会进⼊到餐厅就餐,因此不会出现饿死和死锁的现象。

伪码:semaphore chopstick[5]={1,1,1,1,1};semaphore room=4;void philosopher(int i){while(true){think();wait(room); //请求进⼊房间进餐wait(chopstick[i]); //请求左⼿边的筷⼦wait(chopstick[(i+1)%5]); //请求右⼿边的筷⼦eat();signal(chopstick[(i+1)%5]); //释放右⼿边的筷⼦signal(chopstick[i]); //释放左⼿边的筷⼦signal(room); //退出房间释放信号量room}}B.原理:仅当哲学家的左右两⽀筷⼦都可⽤时,才允许他拿起筷⼦进餐。

⽅法1:利⽤AND 型信号量机制实现:根据课程讲述,在⼀个原语中,将⼀段代码同时需要的多个临界资源,要么全部分配给它,要么⼀个都不分配,因此不会出现死锁的情形。

计算机导论哲学家共餐问题

计算机导论哲学家共餐问题

哲学家共餐问题
●问题描述
1.哲学家的的生活除了吃面条就是思考问题。

2.吃面条的时候需要左、右手各拿起一根筷子。

3.吃完后将筷子放回原处,继续思考问题。

●一个哲学家的活动进程表示
1.思考问题。

2.饿了停止思考,左手拿一只筷子(拿不到就等)。

3.右手拿一只筷子(拿不到就等)。

4.进餐。

5.放下右手筷子。

6.放下左手筷子。

7.重新回到思考问题状态。

●可能出现的问题
1.当所有的哲学家都同时放下筷子时,则所有的哲学家都将拿不到右手的筷子,并处
于等待状态,那么哲学家都将无法进餐,最终饿死。

2.经哲学家的活动进程修改一下,变为右手的筷子拿不到时,就放下左手的筷子。

3.可能在同一个时间,所有的哲学家都拿起了左手的筷子,则自然拿不到右手的筷子,
于是都同时。

哲学家就餐问题防止死锁的其他办法

哲学家就餐问题防止死锁的其他办法

哲学家就餐问题防止死锁的其他办法哲学家就餐问题防止死锁的其他办法:1.只允许不超过4个哲学家同时用餐。

这样就至少有一个哲学家可以得到两个筷子。

Program diningphilosophers:Varfork:array[0..4] of semaphore(:=1);room:semaphore(:=4);i=integer;procedurephilsospher (i:interger);beginrepeatthink;wait(room);wait(fork[i]);wait(fork[(i+1) mod 5]);eat;signal (fork[(i+1) mod 5]);signal (fork[i]);signal (room)foreverend;beginparbeginphilosopher(0);philosopher(1);philosopher(2);philosopher(3);philosopher(4);parend会产生死锁的:Program diningphilosophers: Varfork:array[0..4] of semaphore(:=1);i=integer; procedurephilsospher (i:interger); beginrepeatthink;wait(fork[i]);wait(fork[(i+1) mod 5]);eat;signal (fork[(i+1) mod 5]);signal (fork[i]);foreverend;beginparbeginphilosopher(0);philosopher(1);philosopher(2);philosopher(3);philosopher(4);parendend.2.只有哲学家的左右两子筷子均可用时才允许他拿起筷子。

Pi(i=0,1,…4)RepeatIf odd(i) thenBeginWait(chopstick[i]);Wait(chopstick[i]);ElseBeginWait(chopstick[(i+1) mod 5]);Wait(chopstick[i]);EndEatSignal(chopstick[i]);Signal(chopstick[(i+1) mod 5]);Think;Until false;3.规定奇数号哲学家先拿起左边筷子,然后再去拿右边筷子;而偶数号哲学家则相反。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

红河学院课程设计报告操作系统课程名称:6个哲学家进餐设计题目:院系:工学院专业:计算机科学与技术班级:11计科班曹永前设计者:学号:201101030466指导教师:韦相2013 年 5 月26 日1. 问题描述:一个房间内有6个哲学家,他们的生活就是思考和进食。

哲学家思考后,过一定的时间就会饥饿,饥饿之后就想吃饭,吃饭后再思考。

房间里有一张圆桌,桌子周围放有五把椅子,分别属于五位哲学家每两位哲学家之间有一把叉子,哲学家进食时必须同时使用左右两把叉子。

2. 问题分析1、写出哲学家进餐的算法描述。

用六只筷子解决需要用两双筷子来进餐的六个哲学家,由于每个哲学家都需要其周围的两只筷子,所以筷子是公用信号量,这久需要设置一个互斥信号量,来使六个哲学家互斥的进餐.具体做法将六个信号量设置为0-5,用pv 源于来控制信号量,并将六个哲学家分别编号为0-5.经过仔细分析我们会发现,有这样一个问题存在,就是当每个哲学家都申请到他周围的一只筷子时,由于他们每人都只有一只筷子无法进餐,没有进餐他们就无法释放他们已经得得到的筷子,这样是进餐出于一种僵局,无法继续下去,这就是死锁问题.2、死锁问题的分析与具体的解决方法。

死锁问题就是当每个哲学家都拿到且只拿到一只筷子,这样每个哲学家都无法进餐,也无法释放所得到的筷子,所以解决死锁我们就要从这入手,就是怎样去预防使所有哲学家不要同时去申请他们同一方向的筷子.根据这解决死锁的方法有以下几种:a.每一次最多只能有五个哲学家申请进餐.这样其中的一个哲学家就能申请到两只筷子,就能够进餐,再将筷子释放给其他哲学家进餐.b.用AND信号量,就是哲学家需同时申请其左右两边的筷子,两边都有资源的时候,才能让这个哲学家得到资源,这样哲学家只要申请到筷子就能进餐, 再将筷子释放给其他哲学家进餐.c.用管程机制来实现。

d.我们前面已经将每个哲学家都分配了一个编号,我们可以编号为奇数的哲学家首先去申请其左边的筷子,再去申请其右手边的筷子;让编号为偶数的哲学家,先去申请其右边的筷子,再去申请其左边的筷子.我们可以看出编号为奇数的哲学家左边,与编号为偶数的哲学家的右边为同一只筷子,当其中一个哲学家拿到此筷子后,他另一边的筷子也是空闲的,这样就能避免死锁.主程序中我使用的是最后一种避免死锁的方法.3、用C程序实现哲学家进餐。

(注:可以使用共享变量的方式,也可以使用信号量的方式或其他方法来实现)3.程序清单#include <sys/types.h>#include <sys/ipc.h>#include <sys/sem.h>#include <signal.h>#include <stdio.h>#include <sys/wait.h>#include <stdlib.h>#define N 6 //人数#define THINKTIME 3 // 思考时间#define EATTIME 2 //进餐时间void pop(),vop(),zxj(),think(),eat(); // 初始化main(){int i,semid,pid; //定义变量i为哲学家的编号,semid 信号量semid = semget(0x1234,6,0666|IPC_CREAT);for (i=0;i<N;i++){if (semctl(semid,i,SETV AL,1)==-1)perror("sem set value error");}int pid1,pid2,pid3,pid4,pid5,pid6;while ((pid1=fork())==-1);if (pid1==0){int num=1;zxj(0,semid,num);}while((pid2=fork())==-1);if (pid2==0){int num=1;zxj(1,semid,num);}while ((pid3=fork())==-1);if (pid3==0){int num=1;zxj(2,semid,num);}while ((pid4=fork())==-1);if (pid4==0){int num=1;zxj(3,semid,num);}while ((pid5=fork())==-1);if (pid5==0){int num=1;zxj(4,semid,num);}while ((pid6=fork())==-1);if (pid6==0){int num=1;zxj(5,semid,num);}else{sleep(30);kill(0,15);exit(0);}}void zxj(int i, int semid, int num){while (1)if(i%2==0){think(i);pop(semid ,(i+1)%6);pop(semid,i);eat(i,num);num++;vop(semid,(i+1)%6);vop(semid,i);}else{think(i);pop(semid,i);pop(semid ,(i+1)%6);eat(i,num);num++;vop(semid,i);vop(semid,(i+1)%6);}}void think(int i){printf("我是第%d个哲学家,正在思考,思考时间是%d秒.\n",i,i+THINKTIME);sleep(i+THINKTIME);}void eat(int i,int num){printf("我是第%d个哲学家,正在吃第%d次饭,吃饭时间是%d 秒.\n",i,num,i+EATTIME);sleep(i+EATTIME);}void pop (int semid,int semnum){struct sembuf thesops;thesops.sem_num= semnum;thesops.sem_op = -1;thesops.sem_flg = SEM_UNDO;semop(semid,&thesops,1);}void vop (int semid,int semnum){struct sembuf thesops;thesops.sem_num= semnum;thesops.sem_op = 1;thesops.sem_flg = SEM_UNDO;semop(semid,&thesops,1);}4.运行结果[root@localhost ~]# cc -o qz qz.c[root@localhost ~]# ./qz我是第0个哲学家,正在思考,思考时间是3秒.我是第1个哲学家,正在思考,思考时间是4秒.我是第2个哲学家,正在思考,思考时间是5秒.我是第3个哲学家,正在思考,思考时间是6秒.我是第4个哲学家,正在思考,思考时间是7秒.我是第5个哲学家,正在思考,思考时间是8秒.我是第0个哲学家,正在吃第1次饭,吃饭时间是2秒. 我是第2个哲学家,正在吃第1次饭,吃饭时间是4秒. 我是第0个哲学家,正在思考,思考时间是3秒.我是第4个哲学家,正在吃第1次饭,吃饭时间是6秒. 我是第2个哲学家,正在思考,思考时间是5秒.我是第1个哲学家,正在吃第1次饭,吃饭时间是3秒. 我是第1个哲学家,正在思考,思考时间是4秒.我是第0个哲学家,正在吃第2次饭,吃饭时间是2秒. 我是第4个哲学家,正在思考,思考时间是7秒.我是第3个哲学家,正在吃第1次饭,吃饭时间是5秒. 我是第5个哲学家,正在吃第1次饭,吃饭时间是7秒. 我是第0个哲学家,正在思考,思考时间是3秒.我是第1个哲学家,正在吃第2次饭,吃饭时间是3秒. 我是第3个哲学家,正在思考,思考时间是6秒.我是第1个哲学家,正在思考,思考时间是4秒.我是第2个哲学家,正在吃第2次饭,吃饭时间是4秒. 我是第5个哲学家,正在思考,思考时间是8秒.我是第4个哲学家,正在吃第2次饭,吃饭时间是6秒. 我是第0个哲学家,正在吃第3次饭,吃饭时间是2秒. 我是第2个哲学家,正在思考,思考时间是5秒.我是第0个哲学家,正在思考,思考时间是3秒.我是第1个哲学家,正在吃第3次饭,吃饭时间是3秒. 我是第1个哲学家,正在思考,思考时间是4秒.我是第0个哲学家,正在吃第4次饭,吃饭时间是2秒.我是第3个哲学家,正在吃第2次饭,吃饭时间是5秒.我是第4个哲学家,正在思考,思考时间是7秒.我是第0个哲学家,正在思考,思考时间是3秒.我是第5个哲学家,正在吃第2次饭,吃饭时间是7秒.已终止[root@localhost ~]#5.讨论上述代码中我只是用了改变申请资源次序的方法来预防死锁,在前面的问题分析是我也提到了,其预防死锁的方法并不唯一,下面讲讨论是用其他方法预防死锁问题。

1.是用互斥申请资源就是在同一时刻最多只可以有五位哲学家申请进餐,设置信号量mutex 初始值为5,这样就保证了5个哲学家中至少有1人可以拿到两只筷子,从而避免死锁。

伪码:Mutex=5;Pidi(i=0,1,2,3,4,5)Think();wait(mutex);wait(chopstick[i]);wait(chopstick[i+1] mod 6);signal(mutex);eat();signal(chopstick[i]);signal(chopstick[i+1] mod 6);think();2.采用AND信号量机制AND的基本思想是,将进程所需要的所有资源一次性全部分配给它,但是要有一个资源不能分配给进程,则其他资源也不能分配给该进程(要么所需资源全分配,要么就直接不分配)。

伪码:Pid i(i=0,1,2,3,4,5)Think();swait(chopstick[i],chopstick(i+1) mod 6);eat();signal(chopstick[i],chopstick(i+1) mod 6);think();6.小结1.哲学家问题是进程管理中一个非常经典的例题,是实现多线程同步的问题,这个问题的实现对于我们对进程同步的问题的理解有促进作用。

2.通过设计是我能够熟练的掌握wait 和signal原语;通过对信号量的控制实现进程的互斥与等待;模拟多个进程之间的并发执行。

3.在做的过程当中要不断的上网查阅资料来实现程序功能,课程设计多于的解决问题的能力,以及独立思考的能力都有所锻炼。

4.实践是对理论学习的一个巩固,加深了对理论知识的理解,在设计的过程当中积累经验,并促进理论知识的学习。

相关文档
最新文档