知识卡片
Select处理多路等待
内容
select 在多个可执行 case 中随机选择,避免固定顺序造成饥饿;nil channel 会永久阻塞,可用于动态开关分支。多路等待的公平性来自运行时选择策略。
结构图:
flowchart TD
A[进入 select] --> B[检查多个 case]
B --> C{是否已有就绪}
C -->|有| D[随机选择一个执行]
C -->|无| E[注册到多个等待队列]
E --> F[某个 channel 唤醒]
F --> D
参考来源
- 位置:《Go语言底层原理剖析》第16章《通道与协程间通信》16.3.1、16.3.4节《select随机选择机制》《select与nil》
- 结论依据:原文用"向通道c中写入数据1,虽然两个case都能够读取到通道的内容,但是当我们多次执行程序时会发现,程序有时会输出random 01,有时会输出random 02"说明"case是随机选取的,所以当select有两个通道同时准备好时,会随机执行不同的case";并说明"当select语句的case对nil通道进行操作时,case分支将永远得不到执行",可用于设计交替写入等模式,因此可以推出"select 在多个就绪 case 间随机选择、nil channel 恒阻塞可作动态开关"的结论。
- 原始内容:当多个通道同时准备好执行读写操作时,select会选择哪一个case执行呢?答案是具有一定的随机性……case是随机选取的,所以当select有两个通道同时准备好时,会随机执行不同的case……之前介绍过,一个为nil的通道,不管是读取还是写入都将陷入堵塞状态。当select语句的case对nil通道进行操作时,case分支将永远得不到执行。