The Little Book of Semaphores 信号量小书 第五章 稍欠经典的同步问题 5.4 希尔泽的理发店问题

第五章 稍欠经典的同步问题

 

5.4 希尔泽(Hilzer)的理发店问题

William Stallings [11]提出了一个更为复杂的理发店问题,他将其归功于加州州立大学奇科分校的Ralph Hilzer。


我们的理发店有三把椅子,三个理发师和一个等候区,沙发上可以容纳四个顾客,并为其他顾客提供站立空间。 消防规范将店内的客户总数限制为20个。

如果理发店已满员,则新的顾客不会进入商店。顾客进入后,可以坐在沙发上,如果沙发已经坐满,他就站着。当理发师忙完后,他就服务沙发上等待时间最长的顾客,如果有顾客是站着的,那么站立时间最长的顾客就坐在沙发上。 当顾客理完发后,任何理发师都可以接受付款,但因为只有一个收银机,所以一次只能接受一个客户的付款。 理发师将时间分配在:剪头发、接受付款、在椅子上睡觉等待顾客。


换句话说,以下同步约束适用:

•顾客按顺序调用以下函数:enterShop,sitOnSofa,getHairCut,pay。
•理发师调用cutHair和acceptPayment。
•如果商店已满员,顾客不能调用enterShop。
•如果沙发已满,抵达的顾客不能调用sitOnSofa。
•当顾客调用getHairCut时,应该有一个相应的理发师同时执行cutHair,反之亦然。
•最多可以有三个顾客同时执行getHairCut,最多可以有三个理发师同时执行cutHair。
•顾客必须在理发师接受付款之前付款。
•理发师必须在客户退出之前接受付款。

思考:编写强制执行Hilzer理发店同步约束的代码。

 

5.4.1 希尔泽理发店问题提示

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

The Little Book of Semaphores 信号量小书 第五章 稍欠经典的同步问题 5.4 希尔泽的理发店问题

 

互斥锁mutex保护customers和queue1,customers跟踪商店中的客户数量,queue1是等待沙发座位的线程的信号量列表。

mutex2保护queue2,这是等待椅子的线程的信号量列表。

sofa是复用的,可以强制限制坐在沙发上顾客的最大数量。

customer1表示queue1中有顾客,customer2表示queue2中有顾客。

payment是表示客户已付款的信号,receipt是表示理发师已接受付款的信号。

 

5.4.2 希尔泽理发店问题方案

这个解决方案比我预期的要复杂得多。 我不知道希尔泽是否有更简单的想法,但这是我能做的最好的。

The Little Book of Semaphores 信号量小书 第五章 稍欠经典的同步问题 5.4 希尔泽的理发店问题

第一段与前一个解决方案相同。 当顾客到达时,它会检查计数器并将其自行调整或添加到队列中。 然后它发出理发师的信号。

当顾客离开队列时,它进入多路复用,坐在沙发上并将自己添加到第二个队列。

当它离开那个队列时,它会理发,支付,然后退出。

 

The Little Book of Semaphores 信号量小书 第五章 稍欠经典的同步问题 5.4 希尔泽的理发店问题

每个理发师等待顾客进入,给顾客的信号量发信号,使其脱离排队,然后等待它在沙发上申请座位。 这强制执行FIFO要求。

理发师等待客户加入第二个队列,然后发出信号,允许顾客申请坐上理发椅。

每个理发师都允许一位顾客坐到理发椅上,因此最多可以有三个顾客同时理发。 因为只有一个收银机,所以顾客必须得到互斥锁。 顾客和理发师在收银台会合,然后退出。

该解决方案满足同步约束,但它使沙发未得到充分利用。 因为只有三个理发师,沙发上的顾客永远不会超过三个,所以多路复用是不必要的。

此解决方案位于sync_code / barber3.py(参见3.2)。

我能想到解决这个问题的唯一方法是创建第三种线程,我可以是引座员。 引座员管理queue1,理发师管理queue2。 如果有4个引座员和3个理发师,沙发可以充分利用。

此解决方案位于sync_code / barber4.py中(参见3.2)。