问题描述
桌子坐着5个哲学家,每两个之间有一根筷子,桌子中间是一碗米饭。当哲学家饥饿时会试图拿起左右两根筷子(一根一根地拿)。若筷子在他人手上则需要等待,只有拿到两根筷子才可以进餐,进餐完毕会放下手上筷子
1.找出题中描述的各个进程,确定他们之间的同步和互斥关系
进程有:5个哲学家进程
同步关系(即一前一后执行):无
互斥关系:每个哲学家与左右邻居对其中间筷子的访问是互斥的,其中每根筷子都是一个临界资源
2.根据各个进程操作流程确定P,V操作的大致顺序
key:每个哲学家需要两根筷子(即持有两个临界资源)才能进餐,如何避免资源分配不当造成的死锁现象是关键。
解决方法:对哲学家进程加一些限制,方案1.限制最多允许四个哲学家同时进餐,这样可以保证至少有一个哲学家可以拿到两只筷子;方案2.要求奇数号哲学家先拿左边后拿右边筷子,偶数号相反,这样可以保证相邻两个哲学家只有一个会拿到筷子,另一个会被阻塞从而避免某个哲学家占用一根等待另一根的情况;方案3.各哲学家拿筷子必须互斥进行,这样可以保证当一个哲学家拿筷子拿到一半时被阻塞,不会有其他哲学家继续尝试拿筷子。本例采用第三种方案实现。
3.设置信号量。可定义一个互斥信号量数组mutex[5]={1,1,1,1,1}实现对5根筷子的互斥访问。对哲学家进行0-4的编号,则哲学家i左边筷子编号为i,右边为(i+1)%5
semaphore m = 1;//互斥地取筷子,即保证取左右筷子操作一气呵成
semaphore mutex[5] = {1,1,1,1,1};
Pi()
{
while(1)
{
P(m);
P(mutex[i]);//拿左筷子
P(mutex[(i+1)%5]);//拿右筷子
V(m);
吃饭
V(mutex[i]);//放左筷子
V(mutex[(i+1)%5]);//放右筷子
}
}
mutex信号量是为保证某个哲学家在拿左右筷子的过程中不会有其他哲学家也进行拿筷子操作而发生争抢,故第一个哲学家进程一定会拿到左右两根筷子。