问题描述:

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

约束条件

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

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

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

【操作系统】进程:哲学家进餐问题_信号量

 

记录型信号量解决哲学家进餐问题(可能出现死锁):

【操作系统】进程:哲学家进餐问题_信号量_02

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

解决方案:

(1)最多允许四个人同时去拿左手的筷子,最终能保证至少有一个哲学家能够进餐,并在用完时释放他的筷子,从而使更多的哲学家能够拿筷子。

【操作系统】进程:哲学家进餐问题_解决方案_03

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

AND型信号量

semaphore chopstick[5]={1,1,1,1,1};
do{
 ...
 //think
 ...
 Swait(chopstick[i+1]%5,chopstick[i]);
 ...
 //eat
 ...
 signal(chopstick[i+1]%5,chopstick[i]);
}while(true);
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.

(3)规定奇数号哲学家先拿左边的筷子,偶数号哲学家相反。五位哲学家都先竞争奇数号筷子,获得后,再去竞争偶数号筷子,最后总会有一位哲学家能获得一双筷子。

semaphore chopstick[5]={1,1,1,1,1};
do{
 //thinking
 if(i%2==1){
  wait(chopstick[i]);
  wait(chopstick[(i+1)%5]);
 }else{
  wait(chopstick[(i+1)%5];
  wait(chopstick[i]);
 }
 //eating
 signal(chopstick[i]);
 signal(chopstick[(i+1)%5]);
}while(true);
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.