问题补充说明:规定奇数号的哲学家先拿起他左边的筷子,然后再去拿他右边的筷子;而偶数号的哲学家则相反.按此规定,将是1,2号哲学家竞争1号筷子,3,4号哲学家竞争3号筷子.即五个哲学家都竞争奇数号筷子... 规定奇数号的哲学家先拿起他左边的筷子,然后再去拿他右边的筷子;而偶数号 的哲学家则相反.按此规定,将是1,2号哲学家竞争1号筷子,3,4号哲学家竞争3号筷子.即 五个哲学家都竞争奇数号筷子,获得后,再去竞争偶数号筷子,最后总会有一个哲学家能获 得两支筷子而进餐。 按照这种办法为什么是 是1,2号哲学家竞争1号筷子,3,4号哲学家竞争3号筷子. 展开
设360问答有5个哲学家,共享一张放油把椅路味迅通士规卫列都治双子的桌子,每人分得一吧椅子.但是桌子上总共执友支筷子,在每个人两边分开各放一支.哲学家只有在肚子饥饿时才试图分两次从两边拾起筷子就餐.
就餐条件是:
1)哲学家打班损吗再凯呀察八混想吃饭时,先提出吃饭的要求;
2)提出吃饭要求,并拿到围菜盾坐跑与够支筷子后,方可吃饭;
3)如果筷子已被他人获得,则必须等待该人吃完饭之后才能获取该筷子;
4)任一哲学家在自己未拿到2支筷子吃饭之前,决不放下手中的筷子;
5)刚开帝究升这角肥扩缩德态图始就餐时,只允许2个哲学家请求吃饭.
试问:
1)描述一个保证不会出现两个邻座同时要求吃饭低妒既块专沿花文的算法;
2)描述一个既没有两邻座同时吃饭,又没有人饿死的算法;
3)在什么情况下,5个哲学家全都吃不上饭?
哲学家进餐问题是典型的同步问题.它是由Dijkstra提出并解决的.该问题是描述有五个哲学家,他们的着明生活方式是交替地进行思考和进餐.哲学家们共用一张圆桌,分别唱题齐湖业而玉频坐在周围的五张椅子上.在圆桌上有五个碗和五支筷子,平时一个哲学家进行思考,饥饿时便试图取用其左右岁靠近他的筷子,只有在他拿到两支筷子时才能进餐.进餐完毕,放下筷子继续思考.
利用数记录型信号量解决哲学测宗高这李损细赵某家进餐问题
经分析可知,筷子是临界资源,在一段时间只允许一个哲学家使用.因此,可以用一个信号量表示一支筷子,由这五个信号量构成信号量数组.其描述如下:
varchopstick:array[0,...,4]ofsemaphore;
所有信号量被初始化为1,第i个哲学家的活动可令统同害描述为:
repeat
wait(chopstick)当破实料应采督粒并常;
wait(chopstick[(i+1)mod5]);
...
eat;
...
signal(chopstick);
signal(修减以陆每常附未附局chopstick[(i+1)mod5]);
...
think;
untilfalse;
在以上描述中,哲学家饥饿时,总是一副东村刚具坐互先去拿他左边的筷角子,即执行wait(chopstick造庆高石脸给);成功后,再去拿他右边的细况每形愿处创画培筷子,即执行
wait(chopstick[(i+1)mod5]);,再成让屋洲功后便可进餐.进餐确一它比问措劳课班屋阶完毕,又先放下他左边的筷子,然后放下他右边的筷子.虽然,上述解法可保证不会有两个相临的哲学家同时进餐,但引起死锁是可能的.假如五个哲学家同时饥饿而各自拿起右边的筷子时,就会使五个信号量chopstick均为0;当他们试图去拿右边的筷子时,都将因无筷子可拿而无限期地等待.对于这样的死锁问题可采用以下集中解决方法:
(1)至多只允许四个哲学家同时进餐,以保证至少有一个哲学家能够进餐,最终总会释放出他所使用过的两支筷子,从而可使更多的哲学家进餐.
(2)仅当哲学家的左右两支筷子都可用时,才允许他拿起筷子进餐.
(3)规定奇数号的哲学家先拿起他左边的筷子,然后再去拿他右边的筷子;而偶数号的哲学家则相反.按此规定,将是1,2号哲学家竞争1号筷子,3,4号哲学家竞争3号筷子.即五个哲学家都竞争奇数号筷子,获得后,再去竞争偶数号筷子,最后总会有一个哲学家能获得两支筷子而进餐.
看了整整一个上午的操作系统,看得头都大了。
我们老师的算法的大意好像是用一个总的信号量,只有获得信号量的哲学家才可以拿筷子。
具体算法如下(用类c描述):
#include"所有头文件"
#defineN5
#defineleft(i-1)%N//i的左邻号码
#defineright(i+1)%N//i的右邻号码
#definethink0
#definehungry1
#defineeating2
typedefintsemaphore//信号量是一个特殊的整型变量
intstate[N]//记录每个人的状态
semaphoremutex=1;//设置信号量
semaphores[N];//每个哲学家一个信号量
voidphilosopher(inti)
{
while(true)//无限循环
{
think;
take_chopstick(i);
eat;
put_chopstick(i);
}
}
voidtake_chopstick(inti)
{
p(&mutex);//对信号量的p操作
state=hungry;
test(i);//试图得到两支筷子
v(&mutex);//v操作
p(&s);//得不到筷子则阻塞
}
voidput_chopstick(inti)
{
p(&mutex);
state=think;//进餐结束
test(left);//看左邻是否进餐
test(right);//再看右邻
v(&mutex);
}
voidtest(inti)
{
if(state==hungry&&左邻没进餐&&右邻没进餐)
{
state=eating;
v(&s);
}
}