2.18哲学家问题

视频链接:

https://www.bilibili.com/video/BV1YE411D7nH?p=22

一,问题描述:

一张桌子上有5名哲学家,每两个哲学家之间的桌子上有一根筷子,桌子中间是水煮鱼。哲学家们倾注毕生的经历用于思考和进餐,哲学家在思考时,并不影响他人。只有当哲学家饥饿时,才会试图拿起左右两根筷子(一根,一根地拿起)。如果筷子已经在其他人手上,则需要等待。饥饿的哲学家只有同时拿起两根筷子才可以开始进餐,当进餐完毕后,放下筷子继续思考

二。问题分析:

1,关系分析:系统中有5个哲学家进程,5位哲学家与左右邻居对中间筷子的访问是互斥关系。

2,整理思路:这个问题中只有互斥关系,当与之前不同的是,每个哲学家进程需要同时拥有两个临界资源才可以吃饭。如何避免临界资源分配不当造成的死锁现象,是哲学家问题的精髓。

3,信号量的设置:定义互斥信号量数组chopsticks[5]={1,1,1,1,1}用于实现对5根筷子的互斥访问。并对哲学家按0~4编号,哲学家i左边的筷子编号为i,右边的筷子编号为(i+1)%5

三,具体实现:

问题:如果5个哲学家同时进餐,且在0号哲学家拿起左边筷子时,发生进程切换到1号哲学家拿起左边筷子,又发生进程切换...最终5个哲学家都拿起左边的筷子,每个哲学家都在等待其他哲学家放下筷子,自己不放下筷子的死锁现象

解决方法一:对哲学家进程添加一些限制条件,比如最多运行四个哲学家同时进餐,这样就可以保证至少有一个哲学家可以进餐,进餐完成后放下两根筷子,激活旁边堵塞的哲学家进程。。。所有哲学家都可以进餐

解决方法二:要求奇数号的哲学家先拿左边的筷子,然后再拿右边的筷子,二偶数号哲学家刚好相反。用这种方法可以保证如果相邻两个奇偶号哲学家都想吃饭,那么自会有其中一个哲学家拿起第一只筷子,另外一个没有拿起筷子的哲学家进程会直接堵塞,这就避免了哲学家占有一只筷子后等待另一只的情况、

解决方法三:仅当一个哲学家左右两边筷子都可以使用时才允许其进餐。

方法三的代码实现:


semaphore chopstick[5]={1,1,1,1,1};
semaphore mutex=1;  //互斥的访问筷子
Pi(){//第i个进程此处共有5个进程
    while(1){
        P(mutex);
        P(chopstick[i]);//拿左边的筷子
        P(chopstick[(i+1)%5)]);//拿右边的筷子
        V(mutex);
        吃饭...
        V(chopstick[i]);//放左边的筷子
        V(chopstick[(i+1)%5)]);//放右边的筷子
        思考...
    }
}

假设1号哲学家拿起了,左边1号筷子和右边2号筷子,就会对两只筷子执行P操作使得其他进程不能对他们访问,如果1号哲学家在吃饭时,发生了进程切换2号哲学家,它在拿起左边2号筷子时就会被堵塞,并不会拿起3号筷子占用资源。

猜你喜欢

转载自blog.csdn.net/weixin_44841312/article/details/105328440
今日推荐