第六章 不那么经典的问题
6.4 莫德斯大厅问题(The Modus Hall Problem)
这个问题是由Nathan Karst写的,他是2005年冬天住在Modus Hall的Olin学生之一。
【Modus Hall是模块化建筑的几个昵称之一,又名Mods,第二住宅大厅正在建造时,一些学生就住在里面。】
今年冬天下了一场特别大的雪之后,莫德斯大厅的居民在他们的纸板棚户区和校园其他地方之间开辟了一条类似壕沟的小路。 每天,一些居民通过这条路走进课堂,食物和文明; 我们将忽略每天选择开车到第3层的懒惰学生。我们也会忽略行人的行进方向。 由于某种未知的原因,居住在西厅的学生偶尔会发现有必要冒险去Mods。
不幸的是,这条路不够宽,不允许两个人并排行走。 如果两个Mods人员在路径上的某个地方相遇,一个人会高兴地站在脖子上玩高位漂移来适应另一个。如果两个ResHall居民穿过小路,将会发生类似的情况。 然而,如果Mods异教徒和ResHall 普鲁士相遇,那么一场暴力冲突将接踵而至,胜利者将完全取决于人数的多少;也就是说,人口众多的派系将迫使对方等待。
这与狒狒穿越问题类似(在很多方面),并且附加的扭曲是,临界区的控制由多数规则决定。这有可能成为分类排斥问题的有效且无饥饿的解决方案。
可以避免饥饿,是因为当一个派系控制临界区时,另一派系的成员在队列中累积直到他们达到多数。 然后,当他们等待临界区清除时,他们可以禁止新对手进入。 我希望这个解决方案是高效的,因为它会倾向于批量移动线程,从而允许在临界区实现最大的并发性。
思考:编写以多数规则实现分类排除的代码。
6.4.1 莫德斯大厅问题提示(Modus Hall problem hint)
以下是我在解决方案中使用的变量。
heathens和prudes是计数器,status记录了该区域的状态,可以是“中立(neutral)”、“异教徒规则(heathens rule)”、“普鲁士规则(prudes rule)”、“过渡到异教徒(transition to heathens)”或“过渡到普鲁士(transition to prudes)”。所有这三个都以通常的记分牌模式受互斥锁保护。
heathenTurn和prudeTurn控制对该区域的访问,以便我们可以在转换期间禁止一侧或另一侧。
heathenQueue和prudeQueue是在检入该区域之后和获取该区域之前等待线程的地方。
6.4.2 莫德斯大厅问题方案(Modus Hall problem solution)
这是异教徒的代码:
每个学生检入时,他必须考虑以下情况:
•如果场地是空的,则该学生声称自己是异教徒。
•如果目前由异教徒控制,但是新来的人已经打破平衡,他就锁定普鲁士的旋转门,系统切换到过渡模式。
•如果是普鲁士控制,但是新来的人没有打破平衡,他就加入队列。
•如果系统正在转换为异教徒控制,则新到达的加入队列。
•否则,我们得出结论,要么是异教徒负责,要么是系统正在转变为普鲁士控制。在任何一种情况下,该线程都可以继续运行。
同样,当每个学生检出时,她必须考虑几个情况。
•如果她是最后一个检出的异教徒,她必须考虑以下事项:
- 如果系统处于过渡状态,那意味着旋转的旋转栅门是锁着的,所以她必须打开它。
- 如果有普鲁士在等待,她会给他们发信号并更新status,以便由普鲁士控制。 如果不是,则新状态为“中立”。
•如果她不是最后一个检出的异教徒,她仍然必须检查她的离开是否可能会打破平衡。 在那种情况下,她关闭异教徒旋转栅门并开始过渡。
这种解决方案的一个潜在困难是,任何数量的线程都可以在第3行中断,在那里它们可能已经通过旋转栅门,但是还没有检入。直到他们检入,他们不计数,因此力量的平衡可能无法反映已通过旋转门的线程数量。 此外,当已签入的所有线程也已签出时,转换结束。 此时,可能存在已经通过旋转栅门的线程(两种类型)。
这些行为可能会影响效率——这个解决方案不能保证最大并发性——但如果您接受“多数规则”仅适用于已注册要投票的线程,则它们不会影响正确性。