我们近些天一直在看go协程,关于协程基础和协程间通信,请看之前的博文
初探理解
select
什么是select选择器
什么是select选择器
select选择器和go中switch很相似,只不过select能够处理的对象是chan,那,我们为什么需要select呢,如果我们有多个chan在处理的时候,select可以帮助我们选择符合要求的chan,如果都满足要求,那就回随机选择一个返回。
语法对比一下select和switch
我们对比一下switch和 select语法
对于switch而言,当多个case满足条件的时候,它会顺序执行,不做介入的情况下,执行完一个case后则退出switch, 而select则不同,当case条件满足的时候,它会随机执行case,具体我们看看案例。
switch 案例
switch
我们执行下看下结果
我们通过之前学习的结果可得,若case匹配成功,则会走响应的分支,无法匹配成功,则会走到default分支中。
select案例
反观select呢,我们写个例子看下
我们定义了2个无缓冲管道,一个是bool类型的,一个是int类型的,紧接着我们开启一个协程,中间接入了一个select,分别对boolChan和intChan取值,最后我们等待3秒往boolChan发送true,又3秒,我们向intChan发送3,我们执行下,看下结果
这里简单介绍一下select机制,若在select中没有default分支,那么当没有case条件满足时,它会等待,等待所检测的管道有数据进来,若有default的时候,若执行当下select语句时,若不匹配任何case,则会执行default。
我们再反过来看代码,我们由于没有在select中default分支,所以该语句会等,等某一个case条件匹配时,那正好,我们往boolChan发送了一个true,满足了该case,所以会执行“接收到bool chan 的值” , 好,执行完后,select就执行完毕了,我们再向intChan发送数字3,但是此时我们没有代码去做管道读取,所以会引发deadlock panic
小demo
通过上述案例,我们知晓了select在没有default分支的情况下,只会有一个case被满足,否则会一直等待,所以我们可以根据此案例,写一个发送撤回器。
即,我们写一个小demo,该demo会输出一个信息,我们若在10秒内不干预,则发送,否则撤销发送,
其中核心点,表示select了,我们在其中写入2个case
- cancel bool
- time.after
time.After会在多少时间后返回一个<-chan Time , 而cancel则需要我们自行输入,这意味着,若我们不介入撤销发送,则消息在规定的时间后会发送成功。
好,我们执行下代码
举一反三,我们甚至于利用select可以编写一个服务器心跳包。
总结
我们了解了什么是select,其实从某种意义来说,它和linux select多路复用有点异曲同工之妙,总的来讲,我们在设计的时候若不加入default分支,那么select会一直等待,等待某个case条件满足,满足后,执行分支,退出select,注意,当有多个case满足条件的时候,它会随机选择一个执行,而非顺序执行哦。





