目录
问题描述
解决问题
1、 关系分析:找出题目中描述的各个进程,分析它们之间的同步、互斥关系
系统中有5个哲学家进程,5位哲学家与左右邻居对其中间筷子的访问是互斥关系
2、整理思路:根据各进程的操作流程确定P、V操作的大致顺序
只有互斥关系:与之前不同的是,每个哲学家进程需要同时持有两个临界资源才能开始吃饭
如何避免临界资源分配不当造成的死锁现象,是哲学家问题的精髓
3、 设置信号量:设置需要的信号量,并根据题目要求确定信号量初值(互斥信号量初值一般为1,同步信号量的初始值要看对应资源的初始值时多少)
semaphore chopstick[5] ={1,1,1,1,1}; //用于实现5个筷子的互斥访问
并对哲学家按0~4编号,哲学家i左边的筷子编号为i,右边筷子的编号为(i+1)%5
4、代码实现
初阶
问题:如果五个哲学家进程并发执行,均拿起了自己左手边的筷子,而每位哲学家循环等待右边的人放下筷子(阻塞),这样就会导致死锁问题的出现
进阶:
?如何防止死锁的发生?
- 方法一:可以对哲学家进程施加一些限制条件(互斥信号量),比如最多允许四个哲学家同时进餐。这样就可以保证至少有一个哲学家时可以拿到左右两只筷子的
对于这段代码可以思考三种情况:
- 0号哲学家拿起左筷子后进程切换,2哲学家阻塞等待0号哲学家拿起右裤子并执行B操作后,才能去拿自己的左右筷子(一个哲学家左右两边筷子可以使用时该哲学家是可以一气呵成的去拿自己的筷子的)
- 0号哲学家拿起左右筷子开始吃饭时进程切换,1号哲学家在P操作时不会被阻塞,但是在尝试拿自己的左筷子时会被阻塞,进程切换为2号哲学家则会被直接阻塞在P操作(即使一个科学家左右两边的筷子都没有被占用也可能使用不能这两双筷子)
- 0号哲学家拿起左右筷子开始吃饭时进程切换,4号哲学家在P操作以及拿自己的左筷子时不会被阻塞,但是在拿起自己的右筷子时因为0号哲学家占用了该筷子所以4号哲学家在拿自己的右筷子时会被阻塞
结论:各哲学家拿筷子这件事必须互斥的执行,这保证了即使一个哲学家在拿筷子拿到一半时被阻塞,也不会有别的哲学家会继续尝试那筷子,这样的话,当前正在吃饭的哲学家放下筷子后,被阻塞的哲学家就可以获得等待的筷子了
- 方法二:奇数号哲学家先拿左边的筷子,然后再拿右边的筷子,而偶数号哲学家刚好相反。用这种方法可以保证如果相邻的两个奇偶号哲学家都想吃饭,那么只会有其中一个可以拿起第一只筷子,另一个会直接阻塞,这就避免了占用一支后再等待另一只的情况
结论
哲学家进餐问题的关键在于解决进程死锁(这些进程之间只存在互斥关系,但是与之前解除的互斥关系不同的是,每个进程都需要同时持有两个临界资源,因此就会有”死锁“问题的隐患)
~over~