知识卡片

Select处理多路等待

结构图卡 · 1482.a.2

内容

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分支将永远得不到执行。