问题
这是“信号量小书”中的一个问题。
我们的理发店有三把椅子,三位理发师,以及一个可以在沙发上容纳四位顾客的等候区,可以容纳更多的顾客。消防守则限制商店内的顾客总数为20人。
顾客如与其他顾客合二为一,将不会进入本店。一旦进入,顾客就会在沙发上坐下,或者如果沙发满了,就站在那里。当理发师有空的时候,在沙发上呆得时间最长的顾客就会得到服务,如果有任何顾客站在沙发上,那么在店里呆得时间最长的顾客就会坐在沙发上。当顾客理发完毕后,任何理发师都可以接受付款,但由于只有一个收银机,所以每次只接受一个顾客付款。酒吧老板们把时间分配在剪头发、接受报酬和睡在椅子上等着顾客上。
书本解决方案
以下是本书的解决方案:
共享变量
customers = 0
mutex = Semaphore(1)
mutex2 = Semaphore(1)
sofa = Semaphore(4)
customer1 = Semaphore(0)
customer2 = Semaphore(0)
payment = Semaphore(0)
receipt = Semaphore(0)
queue1 = []
queue2 = []客户线程
self.sem1 = Semaphore(0)
self.sem2 = Semaphore(0)
mutex.wait()
if customers == 20:
mutex.signal()
balk()
customers += 1
queue1.append(self.sem1)
mutex.signal()
# enterShop()
customer1.signal()
self.sem1.wait()
sofa.wait()
# sitOnSofa()
self.sem1.signal()
mutex2.wait()
queue2.append(self.sem2)
mutex2.signal()
customer2.signal()
self.sem2.wait()
sofa.signal()
# getHairCut()
mutex.wait()
# pay()
payment.signal()
receipt.wait()
customers -= 1
mutex.signal()理发螺纹
customer1.wait()
mutex.wait()
sem = queue1.pop(0)
sem.signal()
sem.wait()
mutex.signal()
customer2.wait()
mutex2.wait()
sem2 = queue2.pop(0)
sem2.signal()
mutex2.signal()
# cutHair()
payment.wait()
# acceptPayment()
receipt.signal()问题
据我所知,当第一个顾客(客户1)进来,理发师(理发师1)睡在customer1上时,可以执行以下步骤
queue1添加自己的信号量,向queue1发送信号,并等待自己的queue11唤醒,从customer1队列中弹出客户1的信号量,向它发出信号(唤醒客户1),并等待它。此时,理发师1持有mutex.mutex. 1之前,没有任何其他免费理发师可以让顾客进入理发店,通过sofa (减去它并使它成为3),并发出自己的信号量(醒来理发师1)。
mutex.发出信号。
在这一点上,没有什么能阻止另一个客户经历相同的过程,并最终在客户1之前到达queue2。
因此,我很难理解这本书的解决方案是如何执行这样的约束:“如果有任何站立的顾客,在商店里最长的人就坐在沙发上”。
为了执行这个命令,客户线程似乎应该只在它将自己添加到queue2之后才向self.sem1发出信号,而不是之前。
有人能帮我理解这个解决方案吗?
发布于 2020-01-12 17:29:01
首先,请注意,理发线从代表沙发的queue2头上提取客户,因此,一旦理发师拉起客户,该客户就是在沙发上等待时间最长的客户。
其次,请注意,一旦客户被从queue2中拉出来,理发本身就不需要任何时间,客户就会转移到付款。因此,它的写作方式,客户被拉出队列,并立即移动付款。理发是瞬间的。
因此,如果另一位顾客来了并穿过队列,那么唯一可以选择的方法是,如果有另一位理发师,而第二位顾客在排队的最前面。但是,如果第二个顾客排在第一位,那就意味着另一个理发师已经选择了第一个顾客。所以,这真的不可能发生。
关于self.sem1的问题:它的目的是在客户从队列中被选中后唤醒客户。sem1对应于顾客站立的队列,sem2对应于沙发。客户将信号量添加到队列中,并等待它,因此当理发师线程捡起它时,它可以唤醒客户。因此,它不能真正强制订货,它是在那里唤醒客户时,他/她改变位置。排序由队列强制执行。
https://stackoverflow.com/questions/59698987
复制相似问题