select 是操作系统中的系统调用,我们经常会使用 select、poll 和 epoll 等函数构建 I/O 多路复用模型提升程序的性能。Go 语言的 select 与操作系统中的 select 比较相似,本节会介绍 Go 语言 select 关键字常见的现象、数据结构以及实现原理。
C 语言的 select 系统调用可以同时监听多个文件描述符的可读或者可写的状态,Go 语言中的 select 也能够让 Goroutine 同时等待多个 Channel 可读或者可写,在多个文件或者 Channel状态改变之前,select 会一直阻塞当前线程或者 Goroutine。
![](data:image/png;base64,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)
图 5-5 Select 和 Channel
select 是与 switch 相似的控制结构,与 switch 不同的是,select 中虽然也有多个 case,但是这些 case 中的表达式必须都是 Channel 的收发操作。下面的代码就展示了一个包含 Channel 收发操作的 select 结构:
func fibonacci(c, quit chan int) {
x, y: = 0, 1
for {
select {
case c < -x:
x, y = y, x + y
case <-quit:
fmt.Println("quit")
return
}
}
}
上述控制结构会等待 c <- x 或者 <-quit 两个表达式中任意一个返回。无论哪一个表达式返回都会立刻执行 case 中的代码,当 select 中的两个 case 同时被触发时,会随机执行其中的一个。
5.2.1 现象
当我们在 Go 语言中使用 select 控制结构时,会遇到两个有趣的现象:
1.select 能在 Channel 上进行非阻塞的收发操作;
2.select 在遇到多个 Channel 同时响应时,会随机执行一种情况;
这两个现象是学习 select 时经常会遇到的,我们来深入了解具体场景并分析这两个现象背后的设计原理。
非阻塞的收发
在通常情况下,select 语句会阻塞当前 Goroutine 并等待多个 Channel 中的一个达到可以收发的状态。但是如果 select 控制结构中包含 default 语句,那么这个 select 语句在执行时会遇到以下两种情况:
当存在可以收发的 Channel 时,直接处理该 Channel 对应的 case;
当不存在可以收发的 Channel 时,执行 default 中的语句;
当我们运行下面的代码时就不会阻塞当前的 Goroutine,它会直接执行 default 中的代码。
func main() {
ch: = make(chan int)
select {
case i:
= < -ch:
println(i)
default:
println("default")
}
}
$ go run main.go
default
只要我们稍微想一下,就会发现 Go 语言设计的这个现象很合理。select 的作用是同时监听多个 case 是否可以执行,如果多个 Channel 都不能执行,那么运行 default 也是理所当然的。
非阻塞的 Channel 发送和接收操作还是很有必要的,在很多场景下我们不希望 Channel 操作阻塞当前 Goroutine,只是想看看 Channel 的可读或者可写状态,如下所示:
errCh: = make(chan error, len(tasks))
wg: = sync.WaitGroup {}
wg.Add(len(tasks))
for i: = range tasks {
go func() {
defer wg.Done()
if err: = tasks[i].Run();
err != nil {
errCh < -err
}
}()
}
wg.Wait()
select {
case err:
= < -errCh:
return err
default:
return nil
}
在上面这段代码中,我们不关心到底多少个任务执行失败了,只关心是否存在返回错误的任务,最后的 select 语句能很好地完成这个任务。然而使用 select 实现非阻塞收发不是最初的设计,Go 语言在最初版本使用 x, ok := <-c 实现非阻塞的收发,以下是与非阻塞收发相关的提交:
1.select default 提交支持了 select 语句中的 default1;
2.gc: special case code for single-op blocking and non-blocking selects 提交引入了基于 select 的非阻塞收发2。
3.gc: remove non-blocking send, receive syntax 提交将 x, ok := <-c 语法删除3;
4.gc, runtime: replace closed(c) with x, ok := <-c 提交使用 x, ok := <-c 语法替代 closed(c) 语法判断 Channel 的关闭状态4;
我们可以从上面的几个提交中看到非阻塞收发从最初版本到现在的演变。
随机执行
另一个使用 select 遇到的情况是同时有多个 case 就绪时,select 会选择哪个 case 执行的问题,我们通过下面的代码可以简单了解一下:
func main() {
ch: = make(chan int)
go func() {
for range time.Tick(1 * time.Second) {
ch < -0
}
}()
for {
select {
case <-ch:
println("case1")
case <-ch:
println("case2")
}
}
}
$ go run main.go
case1
case2
case1
...
从上述代码输出的结果中我们可以看到,select 在遇到多个 <-ch 同时满足可读或者可写条件时会随机选择一个 case 执行其中的代码。
这个设计是在十多年前被 select 提交5引入并一直保留到现在的,虽然中间经历过一些修改6,但是语义一直都没有改变。在上面的代码中,两个 case 都是同时满足执行条件的,如果我们按照顺序依次判断,那么后面的条件永远都会得不到执行,而随机的引入就是为了避免饥饿问题的发生。
5.2.2 数据结构
select 在 Go 语言的源代码中不存在对应的结构体,但是我们使用 runtime.scase 结构体表示 select 控制结构中的 case:
type scase struct {
c * hchan // chan
elem unsafe.Pointer // data element
}
因为非默认的 case 中都与 Channel 的发送和接收有关,所以 runtime.scase 结构体中也包含一个 runtime.hchan 类型的字段存储 case 中使用的 Channel。
5.2.3 实现原理
select 语句在编译期间会被转换成 OSELECT 节点。每个 OSELECT 节点都会持有一组 OCASE 节点,如果 OCASE 的执行条件是空,那就意味着这是一个 default 节点。
![](data:image/png;base64,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)
图 5-7 OSELECT 和多个 OCASE
上图展示的就是 select 语句在编译期间的结构,每一个 OCASE 既包含执行条件也包含满足条件后执行的代码。
编译器在中间代码生成期间会根据 select 中 case 的不同对控制语句进行优化,这一过程都发生在 cmd/compile/internal/gc.walkselectcases 函数中,我们在这里会分四种情况介绍处理的过程和结果:
1.select 不存在任何的 case;
2.select 只存在一个 case;
3.select 存在两个 case,其中一个 case 是 default;
4.select 存在多个 case;
上述四种情况不仅会涉及编译器的重写和优化,还会涉及 Go 语言的运行时机制,我们会从编译期间和运行时两个角度分析上述情况。
直接阻塞
首先介绍的是最简单的情况,也就是当 select 结构中不包含任何 case。我们截取 cmd/compile/internal/gc.walkselectcases 函数的前几行代码:
func walkselectcases(cases * Nodes)[] * Node {
n: = cases.Len()
if n == 0 {
return [] * Node {
mkcall("block", nil, nil)
}
}
...
}
这段代码很简单并且容易理解,它直接将类似 select {} 的语句转换成调用 runtime.block 函数:
func block() {
gopark(nil, nil, waitReasonSelectNoCases, traceEvGoStop, 1)
}
runtime.block 的实现非常简单,它会调用 runtime.gopark 让出当前 Goroutine 对处理器的使用权并传入等待原因 waitReasonSelectNoCases。
简单总结一下,空的 select 语句会直接阻塞当前 Goroutine,导致 Goroutine 进入无法被唤醒的永久休眠状态。
单一管道
如果当前的 select 条件只包含一个 case,那么编译器会将 select 改写成 if 条件语句。下面对比了改写前后的代码:
// 改写前
select {
case v, ok < -ch: // case ch <- v
...
}
// 改写后
if ch == nil {
block()
}
v, ok: = < -ch // case ch <- v
...
cmd/compile/internal/gc.walkselectcases 在处理单操作 select 语句时,会根据 Channel 的收发情况生成不同的语句。当 case 中的 Channel 是空指针时,会直接挂起当前 Goroutine 并陷入永久休眠。
非阻塞操作
当 select 中仅包含两个 case,并且其中一个是 default 时,Go 语言的编译器就会认为这是一次非阻塞的收发操作。cmd/compile/internal/gc.walkselectcases 会对这种情况单独处理。不过在正式优化之前,该函数会将 case 中的所有 Channel 都转换成指向 Channel 的地址,我们会分别介绍非阻塞发送和非阻塞接收时,编译器进行的不同优化。
发送
首先是 Channel 的发送过程,当 case 中表达式的类型是 OSEND 时,编译器会使用条件语句和 runtime.selectnbsend 函数改写代码:
select {
case ch < -i:
...
default:
...
}
if selectnbsend(ch, i) {
...
} else {
...
}
这段代码中最重要的就是 runtime.selectnbsend,它为我们提供了向 Channel 非阻塞地发送数据的能力。我们在 Channel 一节介绍了向 Channel 发送数据的 runtime.chansend 函数包含一个 block 参数,该参数会决定这一次的发送是不是阻塞的:
func selectnbsend(c * hchan, elem unsafe.Pointer)(selected bool) {
return chansend(c, elem, false, getcallerpc())
}
由于我们向 runtime.chansend 函数传入了非阻塞,所以在不存在接收方或者缓冲区空间不足时,当前 Goroutine 都不会阻塞而是会直接返回。
接收
由于从 Channel 中接收数据可能会返回一个或者两个值,所以接收数据的情况会比发送稍显复杂,不过改写的套路是差不多的:
// 改写前
select {
case v < -ch: // case v, ok <- ch:
......
default:
......
}
// 改写后
if selectnbrecv( & v, ch) { // if selectnbrecv2(&v, &ok, ch) {
...
} else {
...
}
返回值数量不同会导致使用函数的不同,两个用于非阻塞接收消息的函数 runtime.selectnbrecv 和 runtime.selectnbrecv2 只是对 runtime.chanrecv 返回值的处理稍有不同:
func selectnbrecv(elem unsafe.Pointer, c * hchan)(selected bool) {
selected, _ = chanrecv(c, elem, false)
return
}
func selectnbrecv2(elem unsafe.Pointer, received * bool, c * hchan)(selected bool) {
selected, * received = chanrecv(c, elem, false)
return
}
因为接收方不需要,所以 runtime.selectnbrecv 会直接忽略返回的布尔值,而 runtime.selectnbrecv2 会将布尔值回传给调用方。与 runtime.chansend 一样,runtime.chanrecv 也提供了一个 block 参数用于控制这次接收是否阻塞。
常见流程
在默认的情况下,编译器会使用如下的流程处理 select 语句:
1.将所有的 case 转换成包含 Channel 以及类型等信息的 runtime.scase 结构体;
2.调用运行时函数 runtime.selectgo 从多个准备就绪的 Channel 中选择一个可执行的 runtime.scase 结构体;
3.通过 for 循环生成一组 if 语句,在语句中判断自己是不是被选中的 case;
一个包含三个 case 的正常 select 语句其实会被展开成如下所示的逻辑,我们可以看到其中处理的三个部分:
selv: = [3] scase {}
order: = [6] uint16
for i, cas: = range cases {
c: = scase {}
c.kind = ...
c.elem = ...
c.c = ...
}
chosen, revcOK: = selectgo(selv, order, 3)
if chosen == 0 {
...
break
}
if chosen == 1 {
...
break
}
if chosen == 2 {
...
break
}
展开后的代码片段中最重要的就是用于选择待执行 case 的运行时函数 runtime.selectgo,这也是我们要关注的重点。因为这个函数的实现比较复杂, 所以这里分两部分分析它的执行过程:
1.执行一些必要的初始化操作并确定 case 的处理顺序;
2.在循环中根据 case 的类型做出不同的处理;
初始化
runtime.selectgo 函数首先会进行执行必要的初始化操作并决定处理 case 的两个顺序 — 轮询顺序 pollOrder 和加锁顺序 lockOrder:
func selectgo(cas0 * scase, order0 * uint16, ncases int)(int, bool) {
cas1: = ( * [1 << 16] scase)(unsafe.Pointer(cas0))
order1: = ( * [1 << 17] uint16)(unsafe.Pointer(order0))
ncases: = nsends + nrecvs
scases: = cas1[: ncases: ncases]
pollorder: = order1[: ncases: ncases]
lockorder: = order1[ncases: ][: ncases: ncases]
norder: = 0
for i: = range scases {
cas: = & scases[i]
}
for i: = 1;i < ncases;i++{
j: = fastrandn(uint32(i + 1))
pollorder[norder] = pollorder[j]
pollorder[j] = uint16(i)
norder++
}
pollorder = pollorder[: norder]
lockorder = lockorder[: norder]
// 根据 Channel 的地址排序确定加锁顺序
...
sellock(scases, lockorder)
...
}
轮询顺序 pollOrder 和加锁顺序 lockOrder 分别是通过以下的方式确认的:
1.轮询顺序:通过 runtime.fastrandn 函数引入随机性;
2.加锁顺序:按照 Channel 的地址排序后确定加锁顺序;
随机的轮询顺序可以避免 Channel 的饥饿问题,保证公平性;而根据 Channel 的地址顺序确定加锁顺序能够避免死锁的发生。这段代码最后调用的 runtime.sellock 会按照之前生成的加锁顺序锁定 select 语句中包含所有的 Channel。
循环
当我们为 select 语句锁定了所有 Channel 之后就会进入 runtime.selectgo 函数的主循环,它会分三个阶段查找或者等待某个 Channel 准备就绪:
1.查找是否已经存在准备就绪的 Channel,即可以执行收发操作;
2.将当前 Goroutine 加入 Channel 对应的收发队列上并等待其他 Goroutine 的唤醒;
3.当前 Goroutine 被唤醒之后找到满足条件的 Channel 并进行处理;
runtime.selectgo 函数会根据不同情况通过 goto 语句跳转到函数内部的不同标签执行相应的逻辑,其中包括:
bufrecv:可以从缓冲区读取数据;
bufsend:可以向缓冲区写入数据;
recv:可以从休眠的发送方获取数据;
send:可以向休眠的接收方发送数据;
rclose:可以从关闭的 Channel 读取 EOF;
sclose:向关闭的 Channel 发送数据;
retc:结束调用并返回;
我们先来分析循环执行的第一个阶段,查找已经准备就绪的 Channel。循环会遍历所有的 case 并找到需要被唤起的 runtime.sudog 结构,在这个阶段,我们会根据 case 的四种类型分别处理:
1.当 case 不包含 Channel 时;
这种 case 会被跳过;
2.当 case 会从 Channel 中接收数据时;
如果当前 Channel 的 sendq 上有等待的 Goroutine,就会跳到 recv 标签并从缓冲区读取数据后将等待 Goroutine 中的数据放入到缓冲区中相同的位置;
如果当前 Channel 的缓冲区不为空,就会跳到 bufrecv 标签处从缓冲区获取数据;
如果当前 Channel 已经被关闭,就会跳到 rclose 做一些清除的收尾工作;
3.当 case 会向 Channel 发送数据时;
如果当前 Channel 已经被关,闭就会直接跳到 sclose 标签,触发 panic 尝试中止程序;
如果当前 Channel 的 recvq 上有等待的 Goroutine,就会跳到 send 标签向 Channel 发送数据;
如果当前 Channel 的缓冲区存在空闲位置,就会将待发送的数据存入缓冲区;
4.当 select 语句中包含 default 时;
表示前面的所有 case 都没有被执行,这里会解锁所有 Channel 并返回,意味着当前 select 结构中的收发都是非阻塞的;
![](data:image/png;base64,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)
图 5-8 运行时 selectgo 函数
第一阶段的主要职责是查找所有 case 中是否有可以立刻被处理的 Channel。无论是在等待的 Goroutine 上还是缓冲区中,只要存在数据满足条件就会立刻处理,如果不能立刻找到活跃的 Channel 就会进入循环的下一阶段,按照需要将当前 Goroutine 加入到 Channel 的 sendq 或者 recvq 队列中:
func selectgo(cas0 * scase, order0 * uint16, ncases int)(int, bool) {
...
gp = getg()
nextp = & gp.waiting
for _, casei: = range lockorder {
casi = int(casei)
cas = & scases[casi]
c = cas.c
sg: = acquireSudog()
sg.g = gp
sg.c = c
if casi < nsends {
c.sendq.enqueue(sg)
} else {
c.recvq.enqueue(sg)
}
}
gopark(selparkcommit, nil, waitReasonSelect, traceEvGoBlockSelect, 1)
...
}
除了将当前 Goroutine 对应的 runtime.sudog 结构体加入队列之外,这些结构体都会被串成链表附着在 Goroutine 上。在入队之后会调用 runtime.gopark 挂起当前 Goroutine 等待调度器的唤醒。
![](data:image/png;base64,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)
图 5-9 Goroutine 上等待收发的 sudog 链表
等到 select 中的一些 Channel 准备就绪之后,当前 Goroutine 就会被调度器唤醒。这时会继续执行 runtime.selectgo 函数的第三部分,从 runtime.sudog 中读取数据:
func selectgo(cas0 * scase, order0 * uint16, ncases int)(int, bool) {
...
sg = ( * sudog)(gp.param)
gp.param = nil
casi = -1
cas = nil
sglist = gp.waiting
for _, casei: = range lockorder {
k = & scases[casei]
if sg == sglist {
casi = int(casei)
cas = k
} else {
c = k.c
if int(casei) < nsends {
c.sendq.dequeueSudoG(sglist)
} else {
c.recvq.dequeueSudoG(sglist)
}
}
sgnext = sglist.waitlink
sglist.waitlink = nil
releaseSudog(sglist)
sglist = sgnext
}
c = cas.c
goto retc
...
}
第三次遍历全部 case 时,我们会先获取当前 Goroutine 接收到的参数 sudog 结构,我们会依次对比所有 case 对应的 sudog 结构找到被唤醒的 case,获取该 case 对应的索引并返回。
由于当前的 select 结构找到了一个 case 执行,那么剩下 case 中没有被用到的 sudog 就会被忽略并且释放掉。为了不影响 Channel 的正常使用,我们还是需要将这些废弃的 sudog 从 Channel 中出队。
当我们在循环中发现缓冲区中有元素或者缓冲区未满时就会通过 goto 关键字跳转到 bufrecv 和 bufsend 两个代码段,这两段代码的执行过程都很简单,它们只是向 Channel 中发送数据或者从缓冲区中获取新数据:
bufrecv:
recvOK = true
qp = chanbuf(c, c.recvx)
if cas.elem != nil {
typedmemmove(c.elemtype, cas.elem, qp)
}
typedmemclr(c.elemtype, qp)
c.recvx++
if c.recvx == c.dataqsiz {
c.recvx = 0
}
c.qcount--
selunlock(scases, lockorder)
goto retc
bufsend:
typedmemmove(c.elemtype, chanbuf(c, c.sendx), cas.elem)
c.sendx++
if c.sendx == c.dataqsiz {
c.sendx = 0
}
c.qcount++
selunlock(scases, lockorder)
goto retc
这里在缓冲区进行的操作和直接调用 runtime.chansend 和 runtime.chanrecv 差不多,上述两个过程在执行结束之后都会直接跳到 retc 字段。
两个直接收发 Channel 的情况会调用运行时函数 runtime.send 和 runtime.recv,这两个函数会与处于休眠状态的 Goroutine 打交道:
recv:
recv(c, sg, cas.elem, func() {
selunlock(scases, lockorder)
}, 2)
recvOK = true
goto retc
send:
send(c, sg, cas.elem, func() {
selunlock(scases, lockorder)
}, 2)
goto retc
不过如果向关闭的 Channel 发送数据或者从关闭的 Channel 中接收数据,情况就稍微有一点复杂了:
从一个关闭 Channel 中接收数据会直接清除 Channel 中的相关内容;
向一个关闭的 Channel 发送数据就会直接 panic 造成程序崩溃:
rclose:
selunlock(scases, lockorder)
recvOK = false
if cas.elem != nil {
typedmemclr(c.elemtype, cas.elem)
}
goto retc
sclose:
selunlock(scases, lockorder)
panic(plainError("send on closed channel"))
总体来看,select 语句中的 Channel 收发操作和直接操作 Channel 没有太多出入,只是由于 select 多出了 default 关键字所以会支持非阻塞的收发。
5.2.4 小结
我们简单总结一下 select 结构的执行过程与实现原理,首先在编译期间,Go 语言会对 select 语句进行优化,它会根据 select 中 case 的不同选择不同的优化路径:
1.空的 select 语句会被转换成调用 runtime.block 直接挂起当前 Goroutine;
2.如果 select 语句中只包含一个 case,编译器会将其转换成 if ch == nil { block }; n; 表达式;
首先判断操作的 Channel 是不是空的;
然后执行 case 结构中的内容;
3.如果 select 语句中只包含两个 case 并且其中一个是 default,那么会使用 runtime.selectnbrecv 和 runtime.selectnbsend 非阻塞地执行收发操作;
4.在默认情况下会通过 runtime.selectgo 获取执行 case 的索引,并通过多个 if 语句执行对应 case 中的代码;
在编译器已经对 select 语句进行优化之后,Go 语言会在运行时执行编译期间展开的 runtime.selectgo 函数,该函数会按照以下的流程执行:
1.随机生成一个遍历的轮询顺序 pollOrder 并根据 Channel 地址生成锁定顺序 lockOrder;
2.根据 pollOrder 遍历所有的 case 查看是否有可以立刻处理的 Channel;
如果存在,直接获取 case 对应的索引并返回;
如果不存在,创建 runtime.sudog 结构体,将当前 Goroutine 加入到所有相关 Channel 的收发队列,并调用 runtime.gopark 挂起当前 Goroutine 等待调度器的唤醒;
3.当调度器唤醒当前 Goroutine 时,会再次按照 lockOrder 遍历所有的 case,从中查找需要被处理的 runtime.sudog 对应的索引;
select 关键字是 Go 语言特有的控制结构,它的实现原理比较复杂,需要编译器和运行时函数的通力合作。