经典并发问题: 大型理发店
source link: https://colobu.com/2022/03/06/hilzers-barbershop-problem/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
经典并发问题: 大型理发店
二月二理发店太火了,家家都爆满,这次我们来到Hilzer的理发店,这是一家比较大的理发店。
这家理发店有三位有经验的理发师,每个理发师都有自己独立的理发椅。等待区有一个四座的沙发,等待区还有站一些人等待。还有一个收银台。
- 依照新冠疫情防控的要求,最多允许20个顾客进入。
- 如果有顾客,理发师优先从沙发上叫起等待最久的顾客开始理发;如果没有顾客,理发师则在自己的理发椅上睡觉
- 顾客来到后
- 如果已经有20个顾客,则此顾客离开去其它理发店
- 如果理发师在睡觉,则叫起一位理发师开始理发
- 如果没有空闲的理发师,则选择沙发坐下
- 如果沙发已经坐满,则在休息去站着等待
- 理完发后顾客去收银台去缴费,交完费后理发师把发票交给顾客。顾客就离开,而理发师则准备服务下一位顾客
这一次理发店的问题比上一个理发店问题要复杂很多:
- 等待区分为了站立区和沙发区
- 新增加了收银台,理发师和顾客需要付款和发票的相互等待
- 三位理发师
这类问题使用信号量并发原语比较好,因为理发师、沙发等都是一定数量的资源。理发师和顾客之间缴费和发票之间的同步按理说使用channel比较合适,但是收银台只有一位收银员,还需要处理理发师、顾客和收银员之间的并发,所以我们可以把收银、开发票看成计数器是1的资源。
首先我们还是定义信号量和辅助方法:
接下来我们定义所需的并发原语。
我们使用customerMutex
这个排他锁来控制理发店的顾客数量。
使用sofaSema
控制站立用户坐到沙发上以及理发师叫起等待的顾客。
paySema
用来让顾客去缴费,而receiptSema
让理发师把发票送给顾客,顾客离开。
接下来我们实现理发师的逻辑:
接下来实现顾客的逻辑, 注意customerCount
操作需要使用Mutex保护:
最后把所有的逻辑串起来:
运行这个程序观察并发的执行。
通过这个问题,我们可以好好的练习Semaphore的使用,以及两个goroutine之间信号的传递,控制并发程序的协作执行。
下一章你想了解什么样的经典并发问题呢?
历史并发问题
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK