吸烟者问题读者—写者问题以及哲学家进餐问题的实现
Posted bfhonor
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了吸烟者问题读者—写者问题以及哲学家进餐问题的实现相关的知识,希望对你有一定的参考价值。
一、吸烟者问题
- 假设一个系统有三个抽烟者进程和一个供应者进程。每个抽烟者不停地卷烟并抽掉它,但是要卷起并抽掉一支烟,抽烟者需要有三种材料:烟草、纸和胶水。三个抽烟者中,第一个拥有烟草、第二个拥有纸、第三个拥有胶水。供应者进程无限地提供三种材料,供应者每次将两种材料放桌子上,拥有剩下那种材料的抽烟者卷一根烟并抽掉它,并给供应者进程一个信号告诉完成了,供应者就会放另外两种材料再桌上,这个过程一直重复(让三个抽烟者轮流地抽烟)
本质上这题也属于“生产者-消费者”问题,更详细的说应该是“可生产多种产品的单生产者-多消费者”。
①、关系分析。找出题目中描述的各个进程,分析它们之间的同步、互斥关系。
②、整理思路。根据各进程的操作流程确定P、V操作的大致顺序
③、设置信号量。设置需要的信号量,并根据题目条件确定信号量初值。(互斥信号量初值一般为1,同步信号量的初始值要看对应资源的初始值是多少)
(一)如何实现
- 吸烟者问题可以为我们解决“可以生产多个产品的单生产者”问题提供一个思路。
- 值得吸取的精华是:“轮流让各个吸烟者吸烟”必然需要“轮流的在桌上放上组合一、二、三”,注意体会我们是如何用一个整型变量 i 实现这个“轮流”过程的。
- 如果题目改为“每次随机地让一个吸烟者吸烟”,我们有应该如何用代码写出这个逻辑呢?
- 若一个生产者要生产多种产品(或者说会引发多种前驱事件),那么各个V操作应该放在各自对应的“事件”发生之后的位置。
二、读者—写者问题
- 有读者和写者两组并发进程,共享一个文件,当两个或两个以上的读进程同时访问共享数据时不会产生副作用,但若某个写进程和其他进程(读进程或写进程)同时访问共享数据时则可能导致数据不一致的错误。因此要求:
①允许多个读者可以同时对文件执行读操作;
②只允许一个写者往文件中写信息;
③任一写者在完成写操作之前不允许其他读者或写者工作;
④写者执行写操作前,应让已有的读者和写者全部退出。
- 关系分析。找出题目中描述的各个进程,分析它们之间的同步、互斥关系。
①、两类进程:写进程、读进程
②、互斥关系:写进程—写进程、写进程—读进程。读进程与读进程不存在互斥问题。 - 整理思路。根据各进程的操作流程确定P、V操作的大致顺序
- 设置信号量。设置需要的信号量,并根据题目条件确定信号量初值。(互斥信号量初值一般为1,同步信号量的初始值要看对应资源的初始值是多少)
- 读者-写者问题为我们解决复杂的互斥问题提供了一个参考思路。
- 其核心思想在于设置了一个计数器 count 用来记录当前正在访问共享文件的读进程数。我们可以用count 的值来判断当前进入的进程是否是第一个/最后一个读进程,从而做出不同的处理。
- 另外,对 count 变量的检查和赋值不能一气呵成导致了一些错误,如果需要实现“一气呵成”,自然应该想到用互斥信号量。
- 最后,还要认真体会我们是如何解决“写进程饥饿”问题的。
三、哲学家进餐问题
- 一张圆桌上坐着5名哲学家,每两个哲学家之间的桌上摆一根筷子,桌子的中间是一碗米饭。哲学家们倾注毕生的精力用于思考和进餐,哲学家在思考时,并不影响他人。只有当哲学家饥饿时,才试图拿起左、右两根筷子(一根一根地拿起)。如果筷子已在他人手上,则需等待。饥饿的哲学家只有同时拿起两根筷子才可以开始进餐,当进餐完毕后,放下筷子继续思考。
- 关系分析。系统中有5个哲学家进程,5位哲学家与左右邻居对其中间筷子的访问是互斥关系。
- 整理思路。这个问题中只有互斥关系,但与之前遇到的问题不同的事,每个哲学家进程需要同时持有两个临界资源才能开始吃饭。如何避免临界资源分配不当造成的死锁现象,是哲学家问题的精髓。
- 信号量设置。定义互斥信号量数组
chopstick[5]={1,1,1,1,1}
用于实现对5个筷子的互斥访问。并对哲学家按0~4
编号,哲学家i
左边的筷子编号为i
,右边的筷子编号为(i+1)%5
。
- 上边的情况是不合理的,会产生死锁问题,那么我们应该如何防止死锁的发生呢?
(一)如何实现?
1. 方案一
- ①可以对哲学家进程施加一些限制条件,比如最多允许四个哲学家同时进餐。这样可以保证至少有一个哲学家是可以拿到左右两只筷子的。
2. 方案二
- ②要求奇数号哲学家先拿左边的筷子,然后再拿右边的筷子,而偶数号哲学家刚好相反。用这种方法可以保证如果相邻的两个奇偶号哲学家都想吃饭,那么只会有其中一个可以拿起第一只筷子,另一个会直接阻塞。这就避免了占有一支后再等待另一只的情况。
3. 方案三
- ③仅当一个哲学家左右两支筷子都可用时才允许他抓起筷子。
- 第一种情况:第0个科学家进行进餐;在第0个科学家进餐完之前,其他科学家进程阻塞。只有当第0个科学家进餐完毕后,其他科学家才可以进餐。
- 第二种情况:第0个科学家进行进餐;在第0个科学家进餐完之前,其他科学家进程阻塞。只有当第0个科学家进餐完毕后,其他科学家才可以进餐。但是如果是第0个科学家的右边的第1个科学家进餐的话会发生阻塞,并且即使第2个科学家左右两边都有筷子,也暂时无法取得。
- 第三种情况:第0个科学家进行进餐;在第0个科学家进餐完之前,其他科学家进程阻塞。只有当第0个科学家进餐完毕后,其他科学家才可以进餐。但是如果是第0个科学家的左边的第4个科学家进餐的话会发生阻塞,此时第4个科学家右边的筷子不可用,但是4号仍然会先拿起左边的筷子。
- 哲学家进餐问题的关键在于解决进程死锁。
- 这些进程之间只存在互斥关系,但是与之前接触到的互斥关系不同的是,每个进程都需要同时持有两个临界资源,因此就有“死锁”问题的隐患。
- 如果在考试中遇到了一个进程需要同时持有多个临界资源的情况,应该参考哲学家问题的思想,分析题中给出的进程之间是否会发生循环等待,是否会发生死锁。可以参考哲学家就餐问题解决死锁的三种思路。
以上是关于吸烟者问题读者—写者问题以及哲学家进餐问题的实现的主要内容,如果未能解决你的问题,请参考以下文章
操作系统 王道考研2019 第二章:进程管理 -- 吸烟者问题 & 读者-写者问题 & 哲学家进餐问题
操作系统王道考研 p22-26 生产者消费者问题多生产者多消费者问题吸烟者问题读者写者问题哲学家进餐问题
经典进程的同步问题(生产者--消费者问题哲学家进餐问题读者--写者问题)
操作系统 | 经典进程的同步问题(生产者--消费者问题哲学家进餐问题读者--写者问题)