当前位置:网站首页>go中select语句
go中select语句
2022-07-31 12:28:00 【m0_67401382】
在golang语言中,select语句 就是用来监听和channel有关的IO操作,当IO操作发生时,触发相应的case动作。有了 select语句,可以实现 main主线程 与 goroutine线程 之间的互动。
select {
case <-ch1 : // 检测有没有数据可读
// 一旦成功读取到数据,则进行该case处理语句
case ch2 <- 1 : // 检测有没有数据可写
// 一旦成功向ch2写入数据,则进行该case处理语句
default:
// 如果以上都没有符合条件,那么进入default处理流程
}
注意事项:
select语句 只能用于channel信道的IO操作,每个case都必须是一个信道。
如果不设置 default条件,当没有IO操作发生时,select语句就会一直阻塞;
如果有一个或多个IO操作发生时,Go运行时会随机选择一个case执行,但此时将无法保证执行顺序;
对于case语句,如果存在信道值为nil的读写操作,则该分支将被忽略,可以理解为相当于从select语句中删除了这个case;
对于空的 select语句,会引起死锁;
对于在 for中的select语句,不能添加 default,否则会引起cpu占用过高的问题;
1.先举个简单例子
先创建两个信道,并在 select 前往 c2 发送数据
package main
import (
"fmt"
)
//go的通道选择器 让你可以同时等待多个通道操作。go协程和通道以及选择器的结合是go的一个强大特性。
func main() {
// 在我们的例子中,我们将从两个通道中选择。
c1 := make(chan string, 1)
c2 := make(chan string, 1)
c2 <- "nihao"
//go func() {
// time.Sleep(time.Second * 1)
// c1 <- "one"
//}()
//
//go func() {
// time.Sleep(time.Second * 2)
// c2 <- "two"
//}()
//我们使用 `select` 关键字来同时等待这两个值,并打印各自接收到的值。
//for i := 0; i < 2; i++ {
select {
case msg1 := <-c1:
fmt.Println("received", msg1)
case msg2 := <-c2:
fmt.Println("received", msg2)
default:
fmt.Println("No data received")
}
//}
}
在运行 select 时,会遍历所有(如果有机会的话)的 case 表达式,只要有一个信道有接收到数据,那么 select 就结束,所以输出如下
2. 避免造成死锁
select 在执行过程中,必须命中其中的某一分支。
如果在遍历完所有的 case 后,若没有命中(命中
:也许这样描述不太准确,我本意是想说可以执行信道的操作语句)任何一个 case 表达式,就会进入 default 里的代码分支。
package main
import (
"fmt"
)
//go的通道选择器 让你可以同时等待多个通道操作。go协程和通道以及选择器的结合是go的一个强大特性。
func main() {
// 在我们的例子中,我们将从两个通道中选择。
c1 := make(chan string, 1)
c2 := make(chan string, 1)
//c2 <- "nihao"
//go func() {
// time.Sleep(time.Second * 1)
// c1 <- "one"
//}()
//
//go func() {
// time.Sleep(time.Second * 2)
// c2 <- "two"
//}()
//我们使用 `select` 关键字来同时等待这两个值,并打印各自接收到的值。
//for i := 0; i < 2; i++ {
select {
case msg1 := <-c1:
fmt.Println("received", msg1)
case msg2 := <-c2:
fmt.Println("received", msg2)
//default:
// fmt.Println("No data received")
//}
}
}
但如果你没有写 default 分支,select 就会阻塞,直到有某个 case 可以命中,而如果一直没有命中,select 就会抛出deadlock
的错误,就像下面这样子。
1.解决这个问题的方法有两种
一个是,养成好习惯,在 select 的时候,也写好 default 分支代码,尽管你 default 下没有写任何代码。
另一个是,让其中某一个信道可以接收到数据
2. select 随机性
之前学过 switch 的时候,知道了 switch 里的 case 是顺序执行的,但在 select 里却不是。
通过下面这个例子的执行结果就可以看出
3. select 的超时
当 case 里的信道始终没有接收到数据时,而且也没有 default 语句时,select 整体就会阻塞,但是有时我们并不希望 select 一直阻塞下去,这时候就可以手动设置一个超时时间。
4. 读取/写入都可以
上面例子里的 case,好像都只从信道中读取数据,但实际上,select 里的 case 表达式只要求你是对信道的操作即可,不管你是往信道写入数据,还是从信道读出数据。
5. 总结一下
select 与 switch 原理很相似,但它的使用场景更特殊,学习了本篇文章,你需要知道如下几点区别:
- select 只能用于 channel 的操作(写入/读出),而 switch 则更通用一些;
- select 的 case 是随机的,而 switch 里的 case 是顺序执行;
- select 要注意避免出现死锁,同时也可以自行实现超时机制;
- select 里没有类似 switch 里的 fallthrough 的用法;
- select 不能像 switch 一样接函数或其他表达式。
先自我介绍一下,小编13年上师交大毕业,曾经在小公司待过,去过华为OPPO等大厂,18年进入阿里,直到现在。深知大多数初中级java工程师,想要升技能,往往是需要自己摸索成长或是报班学习,但对于培训机构动则近万元的学费,着实压力不小。自己不成体系的自学效率很低又漫长,而且容易碰到天花板技术停止不前。因此我收集了一份《java开发全套学习资料》送给大家,初衷也很简单,就是希望帮助到想自学又不知道该从何学起的朋友,同时减轻大家的负担。添加下方名片,即可获取全套学习资料哦
边栏推荐
- 尚硅谷–MySQL–基础篇(P1~P95)
- PyQt5快速开发与实战 10.1 获取城市天气预报
- PyQt5 rapid development and actual combat 10.1 Get city weather forecast
- 纷享销客罗旭对话元气森林黄晓枫:零售数字化的终点不是创新,而是数据
- ESP8266-Arduino编程实例-PIR(被动红外)传感器驱动
- Getting started with jmeter performance testing steps (performance testing tool jmeter)
- imx6ull看门狗使用
- Indoor real-time laser SLAM control method based on biological excitation neural network
- Basic use of dosbox [easy to understand]
- 线性表的基本概念
猜你喜欢
chroot命令
Selenium自动化测试之Selenium IDE
DCM middleware family welcomes a new member
centos7安装mysql5.7
ERROR 1064 (42000) You have an error in your SQL syntax; check the manual that corresponds to your
【OpenCV】-边缘检测汇总示例
MySQL日志中“binlog”的三种格式玩起来真爽
SAP ABAP OData 服务如何支持 $filter (过滤)操作试读版
Spark GC日志分析
Google Chrome(谷歌浏览器)安装使用
随机推荐
字符函数和字符串函数
golang八股文整理(持续搬运)
基于生物激励神经网络的室内实时激光SLAM控制方法
Use ODBC in Excel to read data from CDS view on SAP BTP platform
am335x 看门狗驱动&看门狗应用例程序
The 2nd activity of the TOGAF10 Standard Reading Club continues wonderfully, and the highlights will be reviewed!
MySQL日志中“binlog”的三种格式玩起来真爽
[core]-ARMV7-A、ARMV8-A、ARMV9-A 架构简介「建议收藏」
Hybrid brain-computer interface system based on steady-state visual evoked potentials and attentional EEG
立一个flag
Fully Dynamically Constrained Robot Efficient Time-Optimal Trajectory Planning
Addition logic for SAP Commerce Cloud Product Review
集群中增加数据节点与退役数据节点
JVS开发套件产品定位
DCM middleware family welcomes a new member
ipv4和ipv6对比(IPV4)
硬盘分区,拓展C盘,不重装系统,不重装D盘软件的全教程。
【CPU设计实战】简单流水线CPU设计
PyQt5 rapid development and actual combat 10.1 Get city weather forecast
SAP message TK 248 solved