操作系统——哲学家进餐问题
问题描述:
一个圆桌上坐着5名哲学家,每两个哲学家之间的桌子上摆一根筷子,桌子的中间是一碗米饭。哲学家们倾注毕生的精力用于思考和进餐,哲学家在思考时,并不影响他人。只有当哲学家饥饿时,才试图拿起左右两根筷子(一根一根地拿起)。如果筷子已在他人手上,则需要等待。饥饿的哲学家只有同时拿起两根筷子才可以开始进餐,当进餐完毕后,放下筷子继续思考。
1.关系分析
系统中有5个哲学家进程,5位哲学家与左右邻居对其中间筷子的访问是互斥关系。
2.整理思路
哲学家问题只有互斥关系,但与之前遇到的问题不是的是,每个哲学家进程需要同时持有两个临界资源才能开始吃饭。如何避免临界资源分配不当造成的死锁现象,是哲学家问题的精髓。
3.解决方案
信号量设置。定义互斥信号量数组chopstick[5]={1,1,1,1,1}用于实现对5个筷子的互斥访问。并对哲学家按0-4编号,哲学家i左边的筷子编号为i,右边的筷子编号为(i+1)%5,每个哲学家吃饭前依次拿起左,右两支筷子。
但是如果5个哲学家并发地拿起了自己左手边的筷子,那么会出现的问题是每位哲学家循环等待右边的人放下筷子(阻塞),发生死锁。
如何防止死锁的发生呢?来看下面图示:方案一:
4.解决思路
(1)最多允许四个哲学家同时进餐
(2)在每个哲学家进餐之前先判断哲学家是奇数还是偶数
当然,我们还可以这样解决死锁问题:
我们可以规定仅当一个哲学家左右两支筷子都可用时才允许他抓起筷子
我们用信号量mutex,保证了哲学家拿筷子这件事必须互斥的进行。即使一个哲学家在拿筷子拿到一半时被阻塞,也不会有别的哲学家会继续尝试拿筷子。这样的话,当前正在吃饭的哲学家放下筷子后,被阻塞的哲学家就可以获得等待的筷子了。