本文基于 Go 1.14
select

顺序

select

看一个有三个就绪的 channel 的例子:

这三个 channel 的缓冲区都填满了,使得 select 选择时不会堵塞。下面是程序的输出:

在 select 的每次迭代中,case 都会被打乱:

由于 go 不会删除重复的 channel,所以可以使用多次添加 case 来影响结果,代码如下:

输出的结果:

当所有 channel 同时准备就绪时,有 80%的机会选择通道 a。下面来看一下 channel 未就绪的情况。

没有就绪 channels

selectdefault:select
selectselect
select

更多关于 channel 与等待队列的信息,请查看作者另外一篇文章。

上面介绍的逻辑,都是针对于有两个或者以上的活动的 channel,实际上如果只有一个活动的 channel,Go 乐意简化 select。

简化

如果只有一个 case 加上一个 default,例子:

这种情况下。Go 会以非阻塞模式读取 channel 的操作替换 select 语句。如果 channel 在缓冲区中没有任何值,或者发送方准备发送消息,将会运行 default。就像下面这张图:

如果没有 default,则 Go 通过阻塞 channel 的操作方式重写 select 语句。


本文由 原创编译, 荣誉推出