The Little Book of Semaphores 信号量小书 第七章 不太遥远的经典问题 7.6 餐厅问题

第七章 不太遥远的经典问题

7.6 餐厅问题(Dining Hall problem)

这个问题是由Jon Pollack在Olin College的同步课程中编写的。

学生们在餐厅里用餐(dine),然后离开(leave)。 在调用dine之后,调用leave之前,学生被认为“准备离开”。

适用于学生的同步约束是,为了保持社会温和的错觉,学生永远不能独自坐在桌子旁。 如果在完成用餐之前一同用餐的其他所有人都已离开,则该学生被认为是独自坐着。

思考:编写强制执行此约束的代码。

7.6.1 餐厅问题提示

eating和readyToLeave是由互斥锁保护的计数器,因此这是通常的记分板模式。

如果学生准备离开,但另一名学生将独自留在桌旁,她等待okToLeave,直到另一名学生改变情况并发出信号。

7.6.2 餐厅问题方案

如果你分析这些约束条件,你会发现学生只有一种情况需要等待,如果有一个学生正在吃饭,另一个学生想要离开。 但有两种方法可以摆脱这种情况:有另一名学生来吃饭,或者正在就餐的学生要吃完了。

在任何一种情况下,向等待学生发出信号的学生都会更新计数器,因此等待的学生不必返回互斥锁。 这是“我会为你做的”模式的另一个例子。

当学生进入餐厅时,如果她看到一个学生正在吃饭,而另一个正在等待离开,她就会让等待者摆脱困境,并为他递减readyToLeave。

用餐后,学生检查三种情况:

•如果只剩下一名学生,则即将离开的学生必须放弃互斥并等待。
•如果即将离开的学生发现有人在等她,她会向他发出信号并为他们更新计数器。
•否则,她只是递减readyToLeave并离开。

7.6.3 扩展的餐厅问题

如果我们再增加一步,餐厅问题会变得更具挑战性。 当学生来吃午餐时,他们会调用getFood,dine和leave。 在调用getFood之后和调用dine之前,学生被认为是“准备吃饭”。 同样,在调用用餐后,学生被认为“准备离开”。

适用同样的同步约束:学生永远不能独自坐在桌旁。如果有以下情况之一的话,学生被认为是独自坐着:

•当桌上没有其他人准备吃时,她调用dine
•在她完成用餐之前,所有已经调用过dine的人都调用了leave。

思考:编写强制执行这些约束的代码。

7.6.4 扩展的餐厅问题提示

以下是我在解决方案中使用的变量:

readyToEat,eating和readyToLeave是计数器,全部受互斥锁保护。

如果学生处于无法继续的状态,她会等待okToSit或okToLeave,直到另一名学生改变情况并发出信号。
 
我还使用了名为hasMutex的线程内变量来帮助跟踪线程是否持有互斥锁。

7.6.5 扩展的餐厅问题方案

同样,如果我们分析这些约束,我们就会发现只有一种情况,即如果没有人吃饭,也没有其他人准备吃饭,则准备吃饭的学生必须等待。 唯一的出路就是,有其他准备吃的人来了。

同样,如果我们分析这些约束,我们就会意识到,只有一种情况,即准备就餐的学生必须等待,如果没有人吃饭,也没有其他人准备就餐。

与前面的解决方案一样,我使用了“我会为你做的”模式,这样等待的学生就不必返回互斥对象。

这个解决方案与前一个解决方案的主要区别在于,到达空桌的第一个学生必须等待,而第二个学生允许两人继续进行。 无论是哪种情况,我们都无需检查等待离开的学生,因为没有人可以离开一张空桌子!

猜你喜欢

转载自blog.csdn.net/booksyhay/article/details/83008924