为什么需要select?
有时会遇到这种情景:需要对多个channel进行监听。
如图所示,就像一个人监听多个通道一样,假如采用for循环形式
这个方式肯定走不通,原因是一旦某个通道监听阻塞了,下面的部分都不会执行到。有没有一种方法,像治安巡查一样一轮轮的轮询,那么就可以解决这个问题了。
go提供了select,正对应轮询的思路,模式如下:
运行过程
从上往下“巡查”,如果发现哪个case处于可执行状态,就执行该条语句,那么其余语句就不执行了。
如果都不能执行,且有default语句时,就执行default
如果没有default语句,那么select整个就会阻塞(导致所在协程阻塞),直到解除。
但有人会有疑问,上面这些语句不是只能轮询一次吗?这个容易解决,我们给select外层再加一个for循环,这样就可以无限的轮询。
模式基本形成了。
客户和服务端交互模拟
下面先看一个基础的例子,主要用来模仿客户和服务端的交互,模型如下:
分析
- 服务端需要持续服务,因此采用for无限循环形式
- 客户端的返回值就是和超时进行速度PK。