哲学家进餐问题

问题描述:在一张圆桌上坐着5位哲学家,在每两位哲学家中间放一只筷子,桌子中间是一碗米饭,哲学家只要两个动作,要么思考,要么吃饭,但哲学家只有拿起两只筷子才能正常吃饭,如果筷子在别人手里,这位哲学家就被阻塞,当进餐完毕之后,放下筷子继续思考

分析:

五位哲学家与左右邻居对其中间的,筷子的访问是互斥的

每个哲学家进程需要同时持有两个临界资源才能吃饭,如何避免临界资源分配不当造成的死锁现象,是哲学家问题的精髓

信号量设置chopsticks[5] = {1,1,1,1,1},对哲学家按0~4编号,哲学家i左边筷子为i,右边筷子为(i+1)%5

图示

这样我们可以很自然地写出下面的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
semaphore chopsticks[5]={1,1,1,1,1};
Pi(){
while(1){
// 拿左边筷子
P(chopsticks[i]);
// 拿右边筷子
P(chopsticks[(i+1)%5]);
吃饭;
V(chopsticks[(i+1)%5]);
V(chopsticks[i]);
思考;
}
}

但是,如果五个哲学家并发执行,都拿起了左边筷子,那谁也拿不到右边筷子,那谁也吃不了饭,发生死锁,就造成了饥饿

那怎么解决死锁问题呢?

上面分析出现的问题是,哲学家们谁也不能同时拿起左右两双筷子,那我们现在要解决的就是我们至少要让一个哲学家拿到筷子,也就是说要让他一气呵成的拿筷子,拿筷子过程中和任意一个哲学家都存在互斥,解决一气呵成问题就用互斥

1
2
3
4
5
6
7
8
9
10
11
12
13
14
semaphore chopsticks[5]={1,1,1,1,1};
semaphore mutex = 1;
Pi(){
while(1){
P(mutex);
P(chopsticks[i]);
P(chopsticks[(i+1)%5]);
V(mutex);
吃饭;
V(chopsticks[(i+1)%5]);
V(chopsticks[i]);
思考;
}
}

这样就肯定能保证有一个哲学家拿到两只筷子。

-------------本文结束感谢您的阅读-------------