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

开发 前端
如果都不能执行,且有default语句时,就执行default,如果没有default语句,那么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。
责任编辑:武晓燕 来源: 今日头条
相关推荐

2023-03-10 07:46:55

Go开发Channelselect

2020-12-27 10:15:44

Go语言channel管道

2023-05-29 09:25:38

GolangSelect

2023-07-13 08:06:05

应用协程阻塞

2021-10-11 11:58:41

Channel原理recvq

2021-10-09 19:05:06

channelGo原理

2024-09-06 10:48:13

2021-06-09 09:06:52

Go语言算法

2021-02-06 18:19:54

TimeGo语言

2021-09-01 18:38:59

Goselectdefault

2023-07-27 13:46:10

go开源项目

2020-12-02 08:45:36

Go语言

2020-11-30 06:17:03

Go语言

2020-11-26 06:40:24

Go语言基础

2020-11-23 08:54:14

Go语言结构体

2019-12-10 13:55:10

Go指针存储

2024-06-19 10:08:34

GoChannel工具

2022-02-22 08:55:29

SelectPoll/ Epoll

2023-11-03 18:03:54

Web应用Python

2021-09-30 09:21:28

Go语言并发编程
点赞
收藏

51CTO技术栈公众号