第六章 不那么经典的问题
6.2 男女通用的浴室问题
当我的一个朋友离开她在科尔比学院教物理学的职位并在施乐公司找到一份工作时,我写了这个问题。【后来我了解到安德鲁斯的并发编程[1]中出现了一个几乎相同的问题】
她在一个混凝土隔间的地下室里工作,而最近的女士浴室要上两层楼。 她向Uberboss提议,他们将他那一层楼的男士浴室改成男女通用的浴室,有点像Ally McBeal的。
Uberboss同意,只要可以保持以下同步约束:
•浴室里不能同时有男女。
•不应该有超过三名员工在浴室里浪费公司时间。
当然解决方案应该避免死锁。 但是现在,不要担心饿死。 您可以认为浴室配备了您需要的所有信号量。
6.2.1 男女通用浴室提示
以下是我在解决方案中使用的变量:
如果房间是空的,则empty为1,否则为0。
maleSwitch允许男人禁止女性进入房间。 当第一个男性进入时,灯开关锁定empty,禁止女性进入; 当最后一个男性离开时,它解锁empty,允许女性进入。 女性同样使用femaleSwitch。
maleMultiplex和femaleMultiplex确保系统中一次不超过三名男性和三名女性。
6.2.2 男女通用浴室方案
这是女性的代码:
男性的代码类似。
这个解决方案有什么问题吗?
6.2.3 无饿死的男女通用浴室问题
前一个解决方案的问题是它允许饥饿。一长串的女人可以到达和进入,而有一个男人一直在等待,反之亦然。
思考:解决问题。
6.2.4 无饿死的男女通用浴室方案
正如我们之前看到的,我们可以使用一个旋转栅门来允许一种线程停止另一种线程的执行流程。 这次我们来看看男性代码:
只要房间里有男性,新来的男性就会穿过旋转门并进入。 如果男性到达时房间里有女性,则男性会阻塞在旋转门内,这将阻止所有后来到来的(男性和女性)进入,直到里面的人离开。 此时,旋转栅门中的男性进入,可能允许更多的男性进入。
女性代码是相似的,所以如果房间里有男性,到达的女性将被困在旋转门中,禁止额外的男性。
该解决方案可能效率不高。 如果系统繁忙,那么往往会有几个线程,男性和女性,在旋转门上排队。 每次发出empty信号时,一个线程将离开旋转栅门而另一个线程将进入。 如果新线程是异性,它将立即阻止,禁止其他线程。 因此,浴室中通常一次只有1-2个线程,系统不会充分利用可用的并发性。