学习golang(12) 初探:协程(3)多个chan之select选择器

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第9天,点击查看活动详情

我们近些天一直在看go协程,关于协程基础和协程间通信,请看之前的博文

初探理解select

什么是select选择器

什么是select选择器

select选择器和goswitch很相似,只不过select能够处理的对象是chan,那,我们为什么需要select呢,如果我们有多个chan在处理的时候,select可以帮助我们选择符合要求的chan,如果都满足要求,那就回随机选择一个返回。

语法对比一下select和switch

我们对比一下switchselect语法

对于switch而言,当多个case满足条件的时候,它会顺序执行,不做介入的情况下,执行完一个case后则退出switch, 而select则不同,当case条件满足的时候,它会随机执行case,具体我们看看案例。

switch 案例

switch

我们执行下看下结果

我们通过之前学习的结果可得,若case匹配成功,则会走响应的分支,无法匹配成功,则会走到default分支中。

select案例

反观select呢,我们写个例子看下

我们定义了2个无缓冲管道,一个是bool类型的,一个是int类型的,紧接着我们开启一个协程,中间接入了一个select,分别对boolChanintChan取值,最后我们等待3秒往boolChan发送true,又3秒,我们向intChan发送3,我们执行下,看下结果

这里简单介绍一下select机制,若在select中没有default分支,那么当没有case条件满足时,它会等待,等待所检测的管道有数据进来,若有default的时候,若执行当下select语句时,若不匹配任何case,则会执行default

我们再反过来看代码,我们由于没有在selectdefault分支,所以该语句会等,等某一个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满足条件的时候,它会随机选择一个执行,而非顺序执行哦。

posted @ 2022-06-06 18:35  pdudos  阅读(0)  评论(0编辑  收藏  举报  来源