Go开发Channel彻底研究之Select基础

为什么需要select?

有时会遇到这种情景:需要对多个channel进行监听。

目前创新互联建站已为上千余家的企业提供了网站建设、域名、雅安服务器托管、网站托管维护、企业网站设计、管城网站维护等服务,公司将坚持客户导向、应用为本的策略,正道将秉承"和谐、参与、激情"的文化,与客户和合作伙伴齐心协力一起成长,共同发展。

如图所示,就像一个人监听多个通道一样,假如采用for循环形式

for{
d1,ok:=<-c1
//...
d2,ok:=<-c2
//...
....
}

这个方式肯定走不通,原因是一旦某个通道监听阻塞了,下面的部分都不会执行到。有没有一种方法,像治安巡查一样一轮轮的轮询,那么就可以解决这个问题了。

go提供了select,正对应轮询的思路,模式如下:

select{
case xx:
case xx:
case xx:
default:xx
}

运行过程

从上往下“巡查”,如果发现哪个case处于可执行状态,就执行该条语句,那么其余语句就不执行了。

如果都不能执行,且有default语句时,就执行default

如果没有default语句,那么select整个就会阻塞(导致所在协程阻塞),直到解除。

但有人会有疑问,上面这些语句不是只能轮询一次吗?这个容易解决,我们给select外层再加一个for循环,这样就可以无限的轮询。

for{
select{
case xx:
case xx:
........
}
}

模式基本形成了。

客户和服务端交互模拟

下面先看一个基础的例子,主要用来模仿客户和服务端的交互,模型如下:

ch := make(chan string)

//模拟启动服务端
go func(ch chan string) {
for {
data := <-ch
fmt.Println("服务端接收到数据:", data)
time.Sleep(time.Second * 2)
//'roger'表示信息收到的意思..
ch <- "roger"
}
}(ch)

//模拟客户端一次请求
ch <- "hello,服务端!"
select {
case ack := <-ch:
fmt.Println(ack)
case <-time.After(time.Second):
fmt.Println("返回超时...")

}

分析

  1. 服务端需要持续服务,因此采用for无限循环形式
  2. 客户端的返回值就是和超时进行速度PK。

文章名称:Go开发Channel彻底研究之Select基础
本文路径:http://www.gawzjz.com/qtweb/news3/170753.html

网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联