通道阻塞
在之前的 Go 的并发模型 可以了解到,FAN 流水模型可以多个 Goroutine 读一个 Channel 中的数据(FAN-OUT),或者多个 Chanel 将数据发送到一个 Goroutine 中接收(FAN-IN),但是无论是无缓冲通道,还是有缓冲通道,都存在阻塞的情况
无缓冲通道
特点:发送的数据需要被读取后,发送才会完成
阻塞场景:
- 通道中无数据,但执行都通道
- 通道中无数据,向通道中写数据,但无其他协程读取该通道中的数据
代码示例:
// 场景 1 |
有缓冲通道
特点:有缓存时可以向通道中写入数据后直接返回,缓存中有数据时可以从通道中读到数据直接返回,这时有缓存通道是不会阻塞的
阻塞场景:
- 通道的缓存无数据,但执行读通道
- 通道的缓存已经占满,向通道写数据,但无协程读
代码示例:
// 场景 1 |
Select 功能
Select 由关键字 select
和 case
组成,default
不是必须的,如果没其他事可做,可以省略 default
,在多个通道上进行读或写操作,让函数可以处理多个事情,但 1 次只处理 1 个,有以下特性:
- 每次执行
select
,都会只执行其中 1 个case
或者执行default
语句 - 当没有 case 或者 default 可以执行时,select 则阻塞,等待直到有 1 个 case 可以执行
- 当有多个 case 可以执行时,则随机选择 1 个 case 执行
- case 后面跟的必须是读或者写通道的操作,否则编译出错