The Little Book of Semaphores 信号量小书 第七章 不太遥远的经典问题 7.5 法纳尔大厅问题

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

7.5 法纳尔大厅问题(The Faneuil Hall problem)

这个问题是由格兰特哈钦斯(Grant Hutchins)写的,他的灵感来自一位在波士顿法纳尔大厅宣誓加入美国的朋友。

“有三种线程:移民、观众和一名法官。移民必须排队等候,登记,然后坐下。在某个时候,法官进入大楼。当法官在大楼内时,任何人不得进入,移民不得离开。观众可能会离开。一旦所有移民入境,法官可以确认归化。确认后,移民领取他们的美国公民证书。法官在确认后的某个时间离开。观众现在可以像以前一样进入。移民获得证书后,他们可以离开。”

为了使这些需求更具体,让我们给线程一些要执行的函数,并对这些函数进行约束。

  • 移民必须调用enter, checkIn, sitDown, swear, getCertificate 和 leave.
  • 法官调用enter, confirm 和 leave
  • 观众调用enter, spectate 和 leave
  • 当法官在大楼里面时,没有人能调用enter,移民不能调用leave
  • 所有移民调用enter和checkIn之后,法官才能调用confirm
  • 法官执行confirm后,移民才能调用getCertificate

7.5.1 法纳尔大厅问题提示

noJudge是新移民和观众的旋转门; 它还保护entered,entered计算房间内的移民数量。 checked计算已登记的移民人数; 它受互斥锁保护。

法官执行confirm后,发出confirmed信号。

7.5.2 法纳尔大厅问题方案

以下是移民的代码:

移民进入时会通过旋转栅门; 当法官在房间里时,旋转门被锁定。

进入后,移民必须获得互斥锁才能登记并更新checked。如果有法官在等待,最后一个登记的移民会发出allSignedIn信号并将互斥锁传递给法官。

以下是法官的代码:

法官持有noJudge信号量,以禁止移民和观众进入,以及互斥锁mutex,以便访问entered和checked。

如果在法官到达的时候,每个人进入的人都已经登记,则她可以立即进行处理。 否则,她必须放弃互斥并等待。 当最后一个移民登记完并发出allSignedIn信号时,可以认为法官将重新获得互斥锁。

在调用confirm之后,法官向每个已经登记的移民发出一次confirmed信号,然后重置计数器(“我会为你做”的一个例子)。 然后法官离开并释放互斥和noJudge。

在法官发出confirmed信号后,移民同时调用swear和getCertificate,然后等待noJudge旋转门打开后再离开。

观众的代码很容易; 他们必须遵守的唯一限制是noJudge旋转门。

注意:在这个解决方案中,移民在获得证书后可能会被另一位法官卡住,在下一批移民中发誓。 如果发生这种情况,他们可能不得不一直等到另一个宣誓仪式完成。

思考:修改此解决方案以处理额外的约束,即在法官离开后,所有已宣誓的移民必须在法官再次进入之前离开。

7.5.3 扩展的法纳尔大厅问题提示

我的解决方案使用以下附加变量:

由于扩展问题涉及到额外的会合点,我们可以用两个信号量来解决它。
另一个提示:我发现再次使用“传递接力棒”模式很有用。

7.5.4 扩展的法纳尔大厅问题方案

此解决方案的上半部分与之前相同。 差异从第21行开始。移民在这里等待法官离开。

对于法官而言,差异从第18行开始。当法官准备离开时,她不能释放noJudge,因为这将允许更多的移民,可能还有另一名法官进入。 相反,她发出exit信号,允许一名移民离开,并传递互斥锁。

获得信号的移民递减checked,然后将接力棒传递给下一个移民。 离开的最后一个移民发出allGone信号并将互斥锁传递给法官。 这个回传并不是绝对必要的,但是它有一个很好的功能,即法官释放互斥mutex和noJudge来干净利索地结束这一阶段。

扩展问题中观众的代码没有变化。

猜你喜欢

转载自blog.csdn.net/booksyhay/article/details/83007190
今日推荐