哲学家就餐问题共23页
哲学家就餐问题与银行家算法
![哲学家就餐问题与银行家算法](https://img.taocdn.com/s3/m/362bbd537f21af45b307e87101f69e314332faf9.png)
问题解决
方法一
第一种解决死锁问题的办法就是同时只允许四位哲学家同时拿起同一 边的筷子,这样就能保证一定会有一位哲学家能够拿起两根筷子完成 进食并释放资源,供其他哲学家使用,从而实现永动,避免了死锁。 举个最简单的栗子,假定0~3号哲学家已经拿起了他左边的筷子,然后 当4号哲学家企图去拿他左边的筷子的时候,将该哲学家的线程锁住, 使其拿不到其左边的筷子,然后其左边的筷子就可以被3号哲学家拿到, 然后3号哲学家进餐,释放筷子,然后更多的哲学家拿到筷子并进餐。 如何才能实现当4号哲学家企图拿起其左边的筷子的时候将该哲学家 的线程阻塞?这个时候就要用到该问题的提出者迪杰斯特拉(这货还 提出了迪杰斯特拉最短路径算法,著名的银行家算法也是他发明的) 提出的信号量机制。因为同时只允许有四位哲学家同时拿起左筷子, 因此我们可以设置一个信号量r,使其初始值为4,然后每当一位哲学 家企图去拿起他左边的筷子的时候,先对信号量做一次P操作,从而当 第五位哲学家企图去拿做筷子的时候,对r做一次P操作,r = -1,由r < 0得第五位哲学家的线程被阻塞,从而不能拿起左筷子,因此也就避免 了死锁问题。然后当哲学家放下他左边的筷子的时候,就对r做一次V 操作。
死锁,但是处于不安全状态
进程同步模拟设计——哲学家就餐问题
![进程同步模拟设计——哲学家就餐问题](https://img.taocdn.com/s3/m/11e6a7dd6f1aff00bed51eff.png)
课程设计题目进程同步模拟设计—哲学家就餐学院计算机科学与技术专业计算机科学与技术班级计算机姓名指导教师20011 年 1 月19 日需求分析1.1问题描述有五个哲学家围坐在一圆桌旁,桌中央有一盘通心粉,每人面前有一只空盘子,每两人之间放一只筷子,即共5只筷子。
每个哲学家的行为是思考和进餐。
为了进餐,每个哲学家必须拿到两只筷子,并且每个人只能直接从自己的左边或右边去取筷子。
思考时则同时将两支筷子放回原处(此图中以叉子代表筷子)规则:只有拿到两只筷子时,哲学家才能吃饭;如果筷子已经在他人手上,则该哲学家必须等到他人吃完之后才能拿到筷子;任何一个哲学家在自己没有拿到两只筷子吃饭之前,决不放下自己手中的筷子。
由此出现的问题:可能出现死锁问题,因为当五个哲学家都饥饿时,都拿着一支筷子,这样就可能五个哲学家都用不上餐1.2问题分析该问题可用记录型信号量或者是AND型信号量解决。
记录型信号量解决:经分析可知,放在桌子上的筷子是临界资源,在一段时间内只允许一位哲学家使用,为了实现对筷子的互斥使用,可以用一个信号量表示一只筷子,由这五个信号量组成信号量数组。
当哲学家饥饿时总是先拿其左边的筷子,成功后,再去拿右边的筷子,又成功后方可就餐。
进餐完,又先放下他左边的筷子,再放下右边筷子。
这个算法可以保证不会有两个相邻的哲学家同时就餐,但有可能引起死锁。
AND型信号量解决:在哲学家就餐过程中,要求每个哲学家先获得两个临界资源后方能就餐,这在本质上就是AND同步问题,故用AND信号量机制可获得最简洁的解法。
1.3解决方法对于死锁问题可采取这样的几种解决方法:(1)至多只允许四个哲学家同时进餐,以保证至少有一个哲学家可以进餐,最终总会释放出他所用过的两只筷子,从而可使更多的哲学家进餐;(2)仅当左右两只筷子均可用时,才允许哲学家拿起筷子就餐(3)规定奇数号哲学家先拿起右边筷子,然后再去拿左边筷子,而偶数号哲学家则相反。
(4)把筷子顺序编号 fk0, fk1, fk2, fk3, fk4,给每个哲学家分配筷子时,必须依从小号到大号(或者相反顺序)进行。
计算机导论哲学家共餐问题
![计算机导论哲学家共餐问题](https://img.taocdn.com/s3/m/ed2153ccd15abe23482f4db0.png)
哲学家共餐问题
●问题描述
1.哲学家的的生活除了吃面条就是思考问题。
2.吃面条的时候需要左、右手各拿起一根筷子。
3.吃完后将筷子放回原处,继续思考问题。
●一个哲学家的活动进程表示
1.思考问题。
2.饿了停止思考,左手拿一只筷子(拿不到就等)。
3.右手拿一只筷子(拿不到就等)。
4.进餐。
5.放下右手筷子。
6.放下左手筷子。
7.重新回到思考问题状态。
●可能出现的问题
1.当所有的哲学家都同时放下筷子时,则所有的哲学家都将拿不到右手的筷子,并处
于等待状态,那么哲学家都将无法进餐,最终饿死。
2.经哲学家的活动进程修改一下,变为右手的筷子拿不到时,就放下左手的筷子。
3.可能在同一个时间,所有的哲学家都拿起了左手的筷子,则自然拿不到右手的筷子,
于是都同时。
哲学家进餐问题
![哲学家进餐问题](https://img.taocdn.com/s3/m/2d078accda38376baf1fae62.png)
哲学家进餐问题2007/05/16 12:36 P.M./********************philosophers.cpp哲学家进餐问题在多线程中如何避免死锁。
问题描述:有五位哲学家围绕着餐桌坐,每一位哲学家要么思考要么等待,要么吃饭。
为了吃饭,哲学家必须拿起两双筷子(分别放于左右两端)不幸的是,筷子的数量和哲学家相等,所以每只筷子必须由两位哲学家共享下面是一种有问题的解法,因为在某个时刻,五个哲学家同时拿起五根左手边的筷子,则它们会在同一时候对待右手边的筷子,这样会陷入死锁,但是我测试了,这样的几率并不高经过几个小时,还没有出现。
但是我们可以肯定,理论上是肯定会出现死锁的,我们不能老是靠运气办事,怎么解决这个问题呢留给下一步的学习吧要编译此文件请用多线程版的c++库********************/#include <windows.h>#include <iostream>#include <process.h>#include <cstdlib>#include <ctime>using namespace std;unsigned int __stdcall philosopher(void *);void thinking(int);void eating(int);void wait_to_eat(int);void outline(int ,const char *);//全局变量CRITICAL_SECTION crout;//这个变量用来保证输出时不会竞争CRITICAL_SECTION fork[5];//定义五个临界变量,代表五更筷子int main(int argc,char *argv[]){void * hthread[5];int i;unsigned int threadid[5];int arg[5];int count = 5;unsigned long retval;InitializeCriticalSection(&crout);//初始化临界变量for(i=0;i<5;i++){InitializeCriticalSection(fork + i);}//创建五个哲学家for(i = 0; i<5;i++){arg[i] = i;hthread[i] = (void *)_beginthreadex(NULL,0,philosopher,(void *)(arg + i),0,threadid+i);if((int)hthread[i] == -1)//如果线程创建失败返回-1{cerr << "error while create thread " << i <<endl;cerr << "error code : "<< GetLastError() <<endl;}}//等待所有线程结束retval = WaitForMultipleObjects(5,hthread,true,INFINITE);//等待多个线程if(retval == WAIT_FAILED){cerr<< "wait error,error code: "<<GetLastError()<<endl;}for(i = 0; i<5;i++){if(CloseHandle(hthread[i]) == false)//关闭句柄{cerr << "error while close thread " <<i<<endl;cerr << "error code: "<<GetLastError()<<endl;}}return 0;}/*******************哲学家的行为吃饭,等待,思考*******************/unsigned int __stdcall philosopher(void *k){int n = ((int *)k)[0];outline(n," is in!");srand(time(NULL));while(true){thinking(n);wait_to_eat(n);eating(n);}outline(n," is out!");return n;}/*************思考随机一段时间*************/void thinking(int k){outline(k," is thinking...");Sleep((rand()%1000) *5);}/*************吃饭随机一段时间*************/void eating(int k){outline(k," is eating...");Sleep((rand()%1000) *5);LeaveCriticalSection(fork + (k+1)%5);//放下右边的筷子//outline(k," give left");LeaveCriticalSection(fork + k);//放下左边的筷子//outline(k," give right");}/***************等待吃饭需要同时获得他两边的筷子***************/void wait_to_eat(int k){outline(k," is waiting...");EnterCriticalSection(fork + k);//获得左边的筷子//outline(k," take left");EnterCriticalSection(fork + (k + 1)%5);//获得右边的筷子//outline(k," take right");}/********************//没有竞争条件的输出函数********************/void outline(int who,const char *str){EnterCriticalSection(&crout);cout<<"process "<<who<<str<<endl;LeaveCriticalSection(&crout);}/********************philosophers.cpp哲学家进餐问题在多线程中如何避免死锁。
哲学家进餐问题
![哲学家进餐问题](https://img.taocdn.com/s3/m/5827bedd7d1cfad6195f312b3169a4517723e5ab.png)
哲学家进餐问题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); //退出房间释放信号量}}策略二原理:仅当哲学家的左右两支筷子都可用时,才允许他拿起筷子进餐。
哲学家进餐问题
![哲学家进餐问题](https://img.taocdn.com/s3/m/5e83983743323968011c927e.png)
05611 贺美琛 冯文中
问题描述
设有五个哲学家,共用一张放有五把椅子 的餐桌,每人坐在一把椅子上,桌子上有五个 碗和五只叉子,每人两边各放一只叉子。哲学 家们是交替思考和进餐,饥饿时便试图取其左 右最靠近他的叉子。
(1) 只有拿到两只叉子时,哲学家才能吃饭。 (2) 如果叉子已被别人拿走,则必须等别人吃完之后才能拿 到叉子。
算法 C思想:
仅当哲学家的左右两支叉子都可用时, 才允许他拿起叉子进餐。
方法1:利用AND 型信号量机制实现 方法2:利用信号量mutex的保护机制实现
方法1
在一个原语中,将一段代码同时需 要的多个临界资源,要么全部分配给它, 要么一个都不分配,因此不会出现死锁 的情形。当某些资源不够时阻塞调用进 程;由于等待队列的存在,使得对资源的 请求满足FIFO 的要求,因此不会出现饥 饿的情形。
算法改善:
至多只允许四个哲学家同时进餐,以保 证至少有一个哲学家能够进餐,最终总会释 放出他所使用过的两支叉子,从而可使更多 的哲学家进餐。
改进后的算法A
semaphore fork[5]={1,1,1,1,1}; semaphore room=4; 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); //退出房间释放信号量room } }
哲学家就餐
![哲学家就餐](https://img.taocdn.com/s3/m/86b61a4233687e21af45a9fa.png)
利用记录型信号量解决:
• 进分析可知,放在桌子上 的筷子是临界资源,在一 段时间内允许一位哲学家 使用。为了实现对筷子的 互斥使用,可以用一个信 号量表示一只筷子,由这 五个信号量构成信号量数 组。其描述如下:
• • Var chopstick:array[0,…,4]of semaphore; 所有信号量均被初始化为1 ,第i 位哲学家的活动课描述为: • • • • • • • • • • • repeat: wait(chopstick[i]); Wait(chopstick[(i+1)mod5); … eat; … signal(chopstick[i]); signal(chopstick([i+1]mod5); … Think; until false
哲学家用餐
问题:
• 哲学家就餐问题中,一组哲学家围坐在一个圆 桌旁,每个哲学家的左边都只有一只筷子(当 然他的右边也有一只筷子,但是这是他右边哲 学家的左边的筷子),他们吃完了就思考,思 考了一会就会饿,饿了就想吃,然而,为了吃 饭,他们必须获得左边和右边的筷子进餐完毕, 放下筷子继续思考。
五个人五只筷子该如何进行用餐啊
(3)规定奇数号的哲学家先拿起他左边的筷子,然后再去拿他 右边的筷子;而偶数号的哲学家则相反.按此规定,将是1,2号哲 学家竞争1号筷子,3,4号哲学家竞争3号筷子.即五个哲学家都 竞争奇数号筷子,获得后,再去竞争偶数号筷子,最后总会1个哲 学家能获得两支筷子而进餐.其伪码为:
• • • • • • • • • • • Semaphore chopstick[5]={1,1,1,1,1}; void philosopher(int i) { While(true) { Think(); If(i%2==0) //偶数号哲学家, 先右后左 { Wait(chopstick[i+1]mod5); Wait(chopsticl[i]); eat(); • • • • • • • • • • • • signal(chopstick[(i+1)]mod5); singal(chopstick[i]); } else { Wait(chopsticl[i]); Wait(chopstick[i+1]mod5); eat(); singal(chopstick[i]); signal(chopstick[(i+1)]mod5); } }
哲学家就餐问题
![哲学家就餐问题](https://img.taocdn.com/s3/m/40a7ae9ad1d233d4b14e852458fb770bf78a3b14.png)
哲学家就餐问题实验⼀⼀、实验名称:哲学家就餐问题的实现⼆、实验学时:2三、实验内容和⽬的:实验⽬的:实现哲学家就餐问题,要求不能出现死锁。
通过本实验熟悉Linux系统的基本环境,了解Linux下进程和线程的实现。
实验内容:在Unix系统下实现教材2.4.2节中所描述的哲学家就餐问题。
要求显⽰出每个哲学家的⼯作状态,如吃饭,思考。
连续运⾏30次以上都未出现死锁现象。
四、实验原理:由Dijkstra提出并解决的哲学家进餐问题(The Dinning Philosophers Problem)是典型的同步问题。
该问题是描述有五个哲学家共⽤⼀张圆桌,分别坐在周围的五张椅⼦上,在圆桌上有五个碗和五只筷⼦,他们的⽣活⽅式是交替地进⾏思考和进餐。
平时,⼀个哲学家进⾏思考,饥饿时便试图取⽤其左右最靠近他的筷⼦,只有在他拿到两只筷⼦时才能进餐。
进餐完毕,放下筷⼦继续思考。
五、实验器材(设备、元器件)(1)学⽣每⼈⼀台PC,安装WindowsXP/2000操作系统。
(2)局域⽹络环境。
(3)个⼈PC安装VMware虚拟机和Ubuntu系统。
六、实验内容:(⼀)熟悉Ubuntu系统下的多线程编程。
(⼆)实现哲学家就餐问题1. 算法思想规定奇数号哲学家先拿他左边的筷⼦,然后再去拿右边的筷⼦,⽽偶数号哲学家则相反。
按此规定,将是1、2号哲学家竞争1号筷⼦;3、4号哲学家竞争3号筷⼦。
即五位哲学家都⽣竞争奇数号筷⼦,获得后,再去竞争偶数号筷⼦,最后总会有⼀位哲学家能获得两只筷⼦⽽进餐。
2. 流程图3. 程序代码(重要代码请注释)#include#include#include#include#include#define NOC 5 //number of chopstic#define NOP 5 //number of philosopher sem_t chopstic[NOC]; //semaphoreint flag[5]; //philosopher's statusvoid *eat(int i){int position;int temp = 0;int j = (i+1)%NOC;position = i%2;while(1){if(position == 0){ //odd take left first sem_wait(&chopstic[i]);sem_wait(&chopstic[j]);printf("philosopher%d get %d\n", i, j);flag[i] = 1; //philosopher is eatingprintf("waitting:"); //print others' statuswhile(temp < 5){if(!flag[temp])printf("philosopher%d\t", temp);temp++;}temp = 0;printf("\n");printf("eating:");// print others' statuswhile(temp < 5){if(flag[temp])printf("philosopher%d\t", temp);temp++;}printf("\n\n");temp = 0;//printf("\nphilosopher%d is eating\n\n", i); sleep(2);flag[i] = 0;printf("philosopher%d put %d\n", i, i); sem_post(&chopstic[i]); printf("philosopher%d put %d\n", i, j); sem_post(&chopstic[j]); }else{ //even take right firstsem_wait(&chopstic[j]);printf("philosopher%d get %d\n", i, j);sem_wait(&chopstic[i]);printf("philosopher%d get %d\n", i, i);flag[i] = 1;printf("waitting:");while(temp < 5){if(!flag[temp])printf("philosopher%d\t", temp);}temp = 0;printf("\n");printf("eating:");while(temp < 5){if(flag[temp])printf("philosopher%d\t", temp);temp++;printf("\n\n");temp = 0;//printf("\nphilosopher%d is eating\n\n", i);sleep(2);flag[i] = 0;printf("philosopher%d put %d\n", i, j);sem_post(&chopstic[j]);printf("philosopher%d put %d\n", i, i);sem_post(&chopstic[i]);}}}int main(void){int i = 0;int error;pthread_t philosopher[NOP];//init semwhile(i < 5){flag[i] = 0;sem_init(&chopstic[i], 0, 1);i++;}i = 0;//create threadwhile(i < 5){error = pthread_create(&philosopher[i], NULL, (void *)eat, (void *)i);printf("error:create thread failed!!\n");exit(0);}i++;}//destroy threadwhile(i < 5){pthread_join(philosopher[i], NULL);i++;}i = 0;//destroy semwhile(i < 5){sem_destroy(&chopstic[i]);i++;}return 0;}七、实验及结果分析:运⾏结果:udbwxfso@ubuntu:~/Desktop/sy2$ gcc gphilosopher.c -pthread udbwxfso@ubuntu:~/Desktop/sy2$ ./a.out philosopher4 get 4philosopher4 get 0waitting:philosopher0 philosopher1 philosopher2 philosopher3 eating:philosopher4philosopher2 get 2philosopher2 get 3waitting:philosopher0 philosopher1 philosopher3eating:philosopher2 philosopher4philosopher4 put 4philosopher4 put 0philosopher4 get 4philosopher4 get 0waitting:philosopher0 philosopher1 philosopher3eating:philosopher2 philosopher4philosopher2 put 3philosopher2 get 2philosopher2 get 3waitting:philosopher0 philosopher1 philosopher3eating:philosopher2 philosopher4philosopher4 put 4philosopher3 get 4philosopher4 put 0philosopher0 get 0philosopher0 get 1waitting:philosopher1 philosopher3 philosopher4eating:philosopher0 philosopher2philosopher2 put 2philosopher2 put 3philosopher2 get 2philosopher2 get 3waitting:philosopher1 philosopher3 philosopher4eating:philosopher0 philosopher2philosopher2 put 2philosopher2 put 3philosopher2 get 2philosopher2 get 3waitting:philosopher1 philosopher3 philosopher4eating:philosopher0 philosopher2经分析可知,放在桌⼦上的筷⼦是临界资源,在⼀段时间内只允许⼀位哲学家使⽤,为了实现对筷⼦的互斥使⽤,⽤⼀个信号量表⽰⼀只筷⼦,由这五个信号量组成信号量数组。
6个哲学家进餐问题精简版
![6个哲学家进餐问题精简版](https://img.taocdn.com/s3/m/97d81271f46527d3240ce03c.png)
中午发的那个程序有点难理解,下午又参考实验册上那个PV原语例题整了一个容易理解的,再来分享一下下。
如有错误联系我。
操作系统期中考试题(程序设计)题目:6个哲学家进餐问题学期:2009-2010春季完成时间:10周-13周学号:姓名:专业:计算机科学与技术问题描述:一个房间内有6位哲学家,他们的生活就是思考和进食。
哲学家思考后,过一定的时间就会饥饿,饥饿之后就想吃饭,吃饭后再思考。
房间里有一张圆桌,桌子周围放有6把椅子,分别属于6位哲学家,每两位哲学家之间有1支筷子,哲学家进食时必须同时使用左右两支筷子。
1申请的顺序,以避免死锁的产生。
2、写出你的算法如何解决死锁问题,即不能6位哲学家各拿到1支筷子,但都吃不上答:解决死锁的方法是让编号为奇数的哲学家首先申请右手边的筷子,再去申请左手边的筷子;让编号为偶数的哲学家首先去申请左手边的筷子然后再去申请右手边的筷子。
这样死锁的问题即可避免。
因为之所以产生死锁就是每个哲学家都拿了一之筷子才可能会产生死锁,而进行奇右偶左的方法就使得在一个哲学家拿到一只筷子的情况下即可至少使一个邻座的哲学家无法拿到一只筷子。
3、用C程序实现哲学家进餐。
(注:可以使用共享变量的方式,也可以使用信号量的方式来实现)#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;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;}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(50);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+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、程序的运行结果。
哲学家就餐问题(进程管理)
![哲学家就餐问题(进程管理)](https://img.taocdn.com/s3/m/8d5112f3524de518964b7d99.png)
进程管理一、设计目的、功能与要求设计目的:掌握进程管理的相关内容,对进程的同步和互斥,及信号量机制有深入的理解实验内容:模拟实现用信号量机制解决哲学家就餐问题具体要求:任选一种计算机高级语言编程实现实现5个哲学家(5只筷子)的顺利就餐需避免出现死锁使用信号量、及信号量的等待队列使用P操作、V操作能够显示每个哲学家、及每只筷子的状态二、问题的详细描述、需求分析该实验要求模拟实现用信号量机制解决哲学家就餐问题。
哲学家就餐问题详细描述如下:有五个哲学家围坐在一圆桌旁,桌中央有一盘通心粉,每人面前有一只空盘子,有五个哲学家围坐在一圆桌旁,桌中央有一盘通心粉,每人面前有一只空盘子,每两人之间放一只筷子,即共5只筷子。
每个哲学家的行为是思考和进餐。
每个哲学家的行为是思考和进餐。
为了进餐,每个哲学家必须拿到两只筷子,并且每个人只能直接从自己的左边或右边去取筷子。
思考时则同时将两支筷子放回原处时则同时将两支筷子放回原处。
规则:只有拿到两只筷子时,哲学家才能吃饭;只有拿到两只筷子时,哲学家才能吃饭;如果筷子已经在他人手上,则该哲学家必须等到他人吃完之后才能拿到筷子;如果筷子已经在他人手上,则该哲学家必须等到他人吃完之后才能拿到筷子;任何一个哲学家在自己没有拿到两只筷子吃饭之前,决不放下自己手中的筷子。
为了解决哲学家就餐问题同时解决死锁现象,需要设计一定的解决策略。
有这样几种解决办法:1.至多只允许四个哲学家同时进餐,以保证至少有一个哲学家可以进餐,最终总会释放出他所用过的两只筷子,从而可使更多的哲学家进餐;2.仅当左右两只筷子均可用时,才允许哲学家拿起筷子就餐;3.规定奇数号哲学家先拿起右边筷子,然后再去拿左边筷子,而偶数号哲学家则相反。
该实验我采取了第2种解决方案,每个哲学家在确定自己左右两边的筷子都能用时,才能同时拿起两只筷子进餐,进餐完成后同时放下两只筷子。
三、数据结构、功能设计(功能与框图、功能模块说明)该实验使用java的多线程,同时利用到关键字synchronized实现了共享数据的互斥锁定,以保证每只筷子的状态的互斥的。
哲学家就餐问题的算法实现
![哲学家就餐问题的算法实现](https://img.taocdn.com/s3/m/85fabf045b8102d276a20029bd64783e09127d82.png)
哲学家就餐问题的算法实现在哲学家就餐问题中,假定有五位哲学家围坐在一张圆桌旁,每位哲学家面前都放着一碗意面和一把叉子。
这五位哲学家中的每位都有两种活动,一种是思考,一种是就餐。
但是,这五位哲学家只有五支叉子共用,也就是说,每个哲学家只能在自己左右两边分别拿起一把叉子。
若这五位哲学家中有若干人同时拿着左手边的叉子,或者同时拿着右手边的叉子,那么他们都无法就餐。
这时,就需要找到一种算法来解决这个问题。
解法一:Chandy/Misra解法Chandy/Misra解法是一种分布式算法,它的思路是使得每一位哲学家都向右边的人要叉子。
一旦它们都拿到了右边的叉子,就会开始就餐,然后把左右两个叉子都放回去。
这种算法的优点是它具有分布式系统的特点,不会造成资源竞争,而且在算法处理结束后,所有人都不会处于饥饿状态。
但是,这种算法实现的难度比较大,因为需要每个哲学家都向右边的人要叉子,而且需要考虑异常情况。
解法二:Dijkstra解法Dijkstra解法也被称为银行家算法,它的思路是让每一位哲学家先拿一支叉子,只有拿到两支叉子后,才可以开始就餐。
一旦就餐结束,哲学家就将叉子放回去。
这种算法的优点是它比较简单,易于实现。
但是,如果有一位哲学家先拿了一支叉子并且不再释放,那么其他哲学家就会陷入死锁状态。
解法三:Semaphore解法Semaphore解法是以信号量为基础的算法,它的思路是对每支叉子定义一个信号量,并使用信号量来控制哲学家与叉子之间的关系。
一旦一个哲学家想要就餐,就需要请求两个叉子的信号量,如果请求不到,则会被阻塞。
这种算法的优点是它具有可扩展性,而且可以支持多个进程同时使用资源。
但是,它比较复杂,可能会导致死锁。
结论在实际开发中,我们可以根据自己的需求选择合适的算法来解决哲学家就餐问题。
如果要求系统具有分布式系统的特点,可以使用Chandy/Misra解法;如果要求简单易行和易于实现,可以使用Dijkstra解法;如果要求可扩展性和支持多进程,可以选择Semaphore解法。
哲学家进餐问题(操作系统)
![哲学家进餐问题(操作系统)](https://img.taocdn.com/s3/m/ebf7487ea9956bec0975f46527d3240c8447a11a.png)
哲学家进餐问题(操作系统)哲学家进餐问题(操作系统)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 饥饿饥饿是指某个进程或线程因无法获得所需的资源而无法继续执行的情况。
《哲学家进餐问题操作系统》课件模板
![《哲学家进餐问题操作系统》课件模板](https://img.taocdn.com/s3/m/de5309bead02de80d5d8400d.png)
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
操作系统哲学家进餐问题
![操作系统哲学家进餐问题](https://img.taocdn.com/s3/m/3dbcb1f6284ac850ad0242d6.png)
操作系统实习报告一、设计目的:死锁是进程并发执行过程中可能出现的现象,所谓死锁,是指多个进程在运行过程中因争夺资源而造成的一种僵局。
哲学家就餐问题是描述死锁的经典例子。
为了防止死锁,可以采用资源预分配法或者资源按序分配法。
资源预分配法是指进程在运行前一次性地向系统申请它所需要的全部资源,如果系统当前不能够满足进程的全部资源请求,则不分配资源, 此进程暂不投入运行,如果系统当前能够满足进程的全部资源请求, 则一次性地将所申请的资源全部分配给申请进程。
二、设计内容哲学家进餐问题的模拟。
三、开发环境windows环境,Myeclipse平台。
四、分析设计<一>实验原理哲学家进餐问题描述的是五个哲学家共用一张圆桌,分别坐在周围的五张椅子上,在圆桌上有五只碗和五只筷子。
他们的生活方式是交替地进行思考和进餐。
平时,一个哲学家进行思考,饥饿时便试图取用其左右的最靠近他的筷子,只有在他拿到两只筷子时才能进餐。
进餐完毕放下筷子继续思考。
由于:①只有拿到两只筷子时,哲学家才能吃饭;②如果筷子已经在他人手上,则该哲学家必须等到他人吃完之后才能拿到筷子;③任何一个哲学家在自己没有拿到两只筷子吃饭之前,决不放下自己手中的筷子。
则可能出现五个哲学家都饥饿时都拿着一直筷子。
这样就可能五个哲学家都用不上餐。
该问题可用记录型信号量解决,经分析可知,放在桌子上的筷子是临界资源,在一段时间内只允许一位哲学家使用,为了实现对筷子的互斥使用,可以用一个信号量表示一只筷子,由这五个信号量组成信号量数组。
当哲学家饥饿时总是先拿其左边的筷子,成功后,再去拿右边的筷子,又成功后方可就餐。
进餐完,又先放下他左边的筷子,再放下右边筷子。
这个算法可以保证不会有两个相邻的哲学家同时就餐,但有可能引起死锁。
对于死锁问题可采取这样的几种解决方法:(1)至多只允许四个哲学家同时进餐,以保证至少有一个哲学家可以进餐,最终总会释放出他所用过的两只筷子,从而可使更多的哲学家进餐;(2)仅当左右两只筷子均可用时,才允许哲学家拿起筷子就餐(3)规定奇数号哲学家先拿起右边筷子,然后再去拿左边筷子,而偶数号哲学家则相反。
哲学家就餐问题
![哲学家就餐问题](https://img.taocdn.com/s3/m/908c6be4172ded630b1cb65e.png)
管程机制
1. 管程可以看做一个软件模块,它是将共享 的变量和对于这些共享变量的操作封装起 来,形成一个具有一定接口的功能模块, 进程可以调用管程来实现进程级别的并发 控制。 2. 进程只能互斥的使用管程,即当一个进程 使用管程时,另一个进程必须等待,当一 个进程使用完管程后,它必须释放管程并 唤醒等待管程的另一个管程。
一、哲学家就餐问题与C语言:
• 死锁问题
• 其实呢,这个问题在我们计算机中也经常遇到, 用户需要的特定信息由几部分组成,而几个用户 各掌握了特定信息的一部分,彼此不放手,导致 持续的等待我们称之为死锁。在我们学习了哲学 家就餐问题之后,我们可以轻松地解决这个问题
死锁问题解决方法:
(1)至多只允许四个哲学家同时进餐,以保证至少有一个哲学家 能够进餐,最终总会释放出他所使用过的两支筷子,从而可 使更多的哲学家进餐. (2)仅当哲学家的左右两支筷子都可用时,才允许他拿起筷子 进餐. (3)规定奇数号的哲学家先拿起他左边的筷子,然后再去拿他 右边的筷子;而偶数号的哲学家则相反.按此规定,将是1,2号 哲学家竞争1号筷子,3,4号哲学家竞争3号筷子.即五个哲学 家都竞争奇数号筷子,获得后,再去竞争偶数号筷子,最后总 会有一个哲学家能获得两支筷子而进餐.
Chandy/Misra解法
• 1984年,K. Mani Chandy和J. Misra提出了哲学家就餐问题的另一个解 法,允许任意的用户(编号P1, ..., Pn)争用任意数量的资源。与迪科 斯彻的解法不同的是[来源请求],这里编号可以是任意的。 • 1.对每一对竞争一个资源的哲学家,新拿一个餐叉,给编号较低的哲 学家。每只餐叉都是“干净的”或者“脏的”。最初,所有的餐叉都 是脏的。 • 2.当一位哲学家要使用资源(也就是要吃东西)时,他必须从与他竞 争的邻居那里得到。对每只他当前没有的餐叉,他都发送一个请求。 • 3.当拥有餐叉的哲学家收到请求时,如果餐叉是干净的,那么他继续 留着,否则就擦干净并交出餐叉。 • 4.当某个哲学家吃东西后,他的餐叉就变脏了。如果另一个哲学家之 前请求过其中的餐叉,那他就擦干净并交出餐叉。 • 这个解法允许很大的并行性,适用于任意大的问题。
多线程经典哲学家就餐问题C++113种实现
![多线程经典哲学家就餐问题C++113种实现](https://img.taocdn.com/s3/m/99d7251f53ea551810a6f524ccbff121dd36c58b.png)
多线程经典哲学家就餐问题C++113种实现哲学家就餐问题核⼼是 避免死锁1. 同时拿起左右叉⼦class DiningPhilosophers {public:DiningPhilosophers(){}void wantsToEat(int philosopher,function<void()> pickLeftFork,function<void()> pickRightFork,function<void()> eat,function<void()> putLeftFork,function<void()> putRightFork){int r =(philosopher+1)%5;mtx.lock();// 要么左右⼀起拿,要么都不拿lock[philosopher].lock();lock[r].lock();pickLeftFork();pickRightFork();mtx.unlock();eat();putRightFork();putLeftFork();lock[r].unlock();lock[philosopher].unlock();}private:std::mutex lock[5];std::mutex mtx;};2. 改变就餐策略(奇数先拿右,偶数先拿左)class DiningPhilosophers {public:DiningPhilosophers(){}void wantsToEat(int philosopher,function<void()> pickLeftFork, function<void()> pickRightFork, function<void()> eat,function<void()> putLeftFork, function<void()> putRightFork){ int l = philosopher;int r =(philosopher+1)%5;if(philosopher &1){lock[r].lock();lock[l].lock();pickRightFork();pickLeftFork();}else{lock[l].lock();lock[r].lock();pickLeftFork();pickRightFork();}eat();putLeftFork();putRightFork();lock[l].unlock();lock[r].unlock();}private:std::mutex lock[5];};3. 限定就餐⼈数(4个⼈就餐)class Semaphore {public:Semaphore(){}void set_count(int k){count = k;}void signal(){unique_lock<std::mutex>lock(mtx);++count;cv.notify_one();}void wait(){unique_lock<std::mutex>lock(mtx);while(count <=0)cv.wait(lock);--count;}private:int count;std::mutex mtx;std::condition_variable cv;};class DiningPhilosophers {public:DiningPhilosophers(){sem.set_count(4);}void wantsToEat(int philosopher,function<void()> pickLeftFork, function<void()> pickRightFork, function<void()> eat,function<void()> putLeftFork, function<void()> putRightFork){ int l = philosopher;int r =(philosopher+1)%5;sem.wait();lock[l].lock();lock[r].lock();pickLeftFork();pickRightFork();eat();putLeftFork();putRightFork();lock[l].unlock();lock[r].unlock();sem.signal();}private:Semaphore sem;std::mutex lock[5];};。
哲学家就餐问题
![哲学家就餐问题](https://img.taocdn.com/s3/m/d00cd034998fcc22bdd10d09.png)
哲学家就餐问题哲学家就餐问题模拟数学与计算机学院课程设计说明书课程名称: 操作系统原理-课程设计课程代码: 8404061题目: 哲学家就餐问题模拟年级/专业/班: 09级信息与计算科学三班学生姓名: 徐磊学号: 312009********* 开始时间: 2012 年 05 月 14 日完成时间: 2012 年 05月 31 日课程设计成绩:学习态度及平时成绩(30)技术水平与实际能力(20)创新(5)说明书撰写质量(45)总分(100)指导教师签名:年月日哲学家就餐问题模拟I 目录1 引言................................................. 错误!未定义书签。
1.1问题的提出 ................................................................................... 错误!未定义书签。
1.2任务与分析........................................................................................ 错误!未定义书签。
2.总体设计思想及相关知识.............................. 错误!未定义书签。
2.1总体设计思想 ......................................... 错误!未定义书签。
2.2临界区互斥编程原理........................................................................ 错误!未定义书签。
3 程序运行平台........................................... 错误!未定义书签。
4 程序类的说明........................................... 错误!未定义书签。