Go 语言 select 都能做什么?
原文链接: Go 语言 select 都能做什么?
在 Go 语言中,select 是一个关键字,用于监听和 channel 有关的 IO 操作。
通过 select 语句,我们可以同时监听多个 channel,并在其中任意一个 channel 就绪时进行相应的处理。
本文将总结一下 select 语句的常见用法,以及在使用过程中的注意事项。
基本语法
select 语句的基本语法如下:
select {
case <-channel1:
// 通道 channel1 就绪时的处理逻辑
case data := <-channel2:
// 通道 channel2 就绪时的处理逻辑
default:
// 当没有任何通道就绪时的默认处理逻辑
}
看到这个语法,很容易想到 switch 语句。
虽然 select 语句和 switch 语句在表面上有些相似,但它们的用途和功能是不同的。
switch 用于条件判断,而 select 用于通道操作。不能在 select 语句中使用任意类型的条件表达式,只能对通道进行操作。
使用规则
虽然语法简单,但是在使用过程中,还是有一些地方需要注意,我总结了如下四点:
select语句只能用于通道操作,用于在多个通道之间进行选择,以监听通道的就绪状态,而不是用于其他类型的条件判断。select语句可以包含多个case子句,每个case子句对应一个通道操作。当其中任意一个通道就绪时,相应的case子句会被执行。- 如果多个通道都已经就绪,
select语句会随机选择一个通道来执行。这样确保了多个通道之间的公平竞争。 select语句的执行可能是阻塞的,也可能是非阻塞的。如果没有任何一个通道就绪且没有默认的default子句,select语句会阻塞,直到有一个通道就绪。如果有default子句,且没有任何通道就绪,那么select语句会执行default子句,从而避免阻塞。
多路复用
select 最常见的用途之一,同时监听多个通道,并根据它们的就绪状态执行不同的操作。
package main
import (
"fmt"
"time"
)
func main() {
c1 := make(chan string)
c2 := make(chan string)
go func() {
time.Sleep(3 * time.Second)
c1 <- "one"
}()
go func() {
time.Sleep(3 * time.Second)
c2 <- "two"
}()
select {
case msg := <-c1:
fmt.Println(msg)
case msg := <-c2:
fmt.Println(msg)
}
}
执行上面的代码,程序会随机打印 one 或者 two,如果通道为空的话,程序就会一直阻塞在那里。
非阻塞通信
当通道中没有数据可读或者没有缓冲空间可写时,普通的读写操作将会阻塞。
但通过 select 语句,我们可以在没有数据就绪时执行默认的逻辑,避免程序陷入无限等待状态。
package main
import (
"fmt"
)
func main() {
channel := make(chan int)
select {
case data := <-channel:
fmt.Println("Received:", data)
default:
fmt.Println("No data available.")
}
}
执行上面代码,程序会执行 default 分支。
输出:
No data available.
超时处理
通过结合 select 和 time.After 函数,我们可以在指定时间内等待通道就绪,超过时间后执行相应的逻辑。
package main
import (
"fmt"
"time"
)
func main() {
channel := make(chan int)
select {
case data := <-channel:
fmt.Println("Received:", data)
case <-time.After(3 * time.Second):
fmt.Println("Timeout occurred.")
}
}
执行上面代码,如果 channel 在 3 秒内没有数据可读,select 会执行 time.After 分支。
输出:
Timeout occurred.
以上就是本文的全部内容,如果觉得还不错的话欢迎点赞,转发和关注,感谢支持。
推荐阅读:
Go 语言 select 都能做什么?的更多相关文章
- PHP语言学习之php做图片上传功能
本文主要向大家介绍了PHP语言学习之php做图片上传功能,通过具体的内容向大家展示,希望对大家学习php语言有所帮助. 今天来做一个图片上传功能的插件,首先做一个html文件:text.php < ...
- MySQL 使用SELECT ... FOR UPDATE 做事务写入前的确认(转)
Select…For Update语句的语法与select语句相同,只是在select语句的后面加FOR UPDATE [NOWAIT]子句. 该语句用来锁定特定的行(如果有where子句,就是满足w ...
- [语法]C语言中二维数组做输入参数
C语言中二维数组做输入参数时, 可以同时指定各维长度, 可以只指定第二维的长度, 不可以只指定第一维的长度, 不可以各维长度都不指定. 一句话总结:要指定至少指定第二维,都不指定是不行的. 具体栗子如 ...
- NodeJS什么都能做,为什么还要JAVA?
这张图看起来简单而且很好理解,但没尝试过,会有很多疑问. SPA模式中,后端已供了所需的数据接口,view前端已经可以控制,为什么要多加NodeJS这一层? 多加一层,性能怎么样? 多加一层,前端的工 ...
- Java 程序员每天都在做什么?
作为一名 在大.中.小微企业都待过 的 Java 开发者,今天和大家分享下自己在不同公司的工作日常和收获.包括一些个人积累的工作提升经验,以及一些 Java 学习的方法和资源. 先从我的第一份 Jav ...
- 微信小程序来了,小程序都能做些什么
2017年的微信大动作就是微信小程序了,到底小程序都能做些什么?这是很多人关注的热点,小程序开发对企业又有什么帮助呢?下面让厦门微信小程序开发公司来为你就分析下. 微信小程序与APP的关系 ...
- 腾讯QQ会员技术团队:人人都可以做深度学习应用:入门篇(下)
四.经典入门demo:识别手写数字(MNIST) 常规的编程入门有"Hello world"程序,而深度学习的入门程序则是MNIST,一个识别28*28像素的图片中的手写数字的程序 ...
- linux c语言 select函数用法
linux c语言 select函数用法 表头文件 #i nclude<sys/time.h> #i nclude<sys/types.h> #i nclude<unis ...
- 【腾讯Bugly干货分享】人人都可以做深度学习应用:入门篇
导语 2016年,继虚拟现实(VR)之后,人工智能(AI)的概念全面进入大众的视野.谷歌,微软,IBM等科技巨头纷纷重点布局,AI 貌似将成为互联网的下一个风口. 很多开发同学,对人工智能非常感兴趣, ...
- Muduo学习笔记(一) 什么都不做的EventLoop
Muduo学习笔记(一) 什么都不做的EventLoop EventLoop EventLoop的基本接口包括构造.析构.loop(). One Loop Per Thread 一个线程只有一个Eve ...
随机推荐
- CQOI2013vp记
新Nim游戏 因为第一次操作与其它操作不同,考虑拿出来单独做,剩下的操作就变成了 Nim游戏 了. 回忆一下 Nim游戏 先手必胜的条件是什么,是所有数的异或和不为 \(0\),那么这题就转化为求原集 ...
- P5356 [Ynoi2017] 由乃打扑克
md调了5h才调出来恶心坏了没想到这么快就做了第二道Ynoi 据说这题其实不卡常 屠龙宝刀点击就送 题面也很清楚,给定两种操作,一种是区间加,一种是询问区间内第 k 小的数的值是多少. 对于区间加,在 ...
- ChatGPT Plugin 插件开发:基于 ASP.NET Core Minimal API
前言 这是一篇ChatGPT插件开发教程,描述如何使用 ASP.NET Core Minimal API 开发 ChatGPT 插件,以最简单的 Todo List 指导示例作为入门教程. 这个Tod ...
- 粘包/拆包问题一直都存在,只是到TCP就拆不动了。
OSI open-system-Interconnection TCP/IP 5层协议栈 应用层和操作系统的边界是 系统调用 ,对应到网络编程是socket api TCP/UDP 概况 TCP粘包问 ...
- 文心一言 VS chatgpt (13)-- 算法导论3.1 8题 3.2 1题
八.可以扩展我们的记号到有两个参数n和m的情形,其中的n和m可以按不同速率独立地趋于无穷.对于给定的函数g(n, m),用O(g(n, m))来表示以下函数集: O(g(n, m)) = 对Ω(g(n ...
- 2022-07-31:给出一个有n个点,m条有向边的图, 你可以施展魔法,把有向边,变成无向边, 比如A到B的有向边,权重为7。施展魔法之后,A和B通过该边到达彼此的代价都是7。 求,允许施展一次魔法
2022-07-31:给出一个有n个点,m条有向边的图, 你可以施展魔法,把有向边,变成无向边, 比如A到B的有向边,权重为7.施展魔法之后,A和B通过该边到达彼此的代价都是7. 求,允许施展一次魔法 ...
- vue全家桶进阶之路46:Vue3 Axios拦截器
在Vue.js 3中,使用Axios与Vue.js 2.x中类似,但是需要进行一些修改和更新,下面是Vue.js 3中Axios的定义和使用方式: 首先,你需要安装Axios和Vue.js 3.x,可 ...
- ModuleNotFoundError: No module named 'flask_login'
ModuleNotFoundError: No module named 'flask_login' 解决: pip install flask_login
- 【CF】Round #618 div2 C(文末有技巧)
目录 round #618 div2 C(文末有技巧) 题目: 样例输入输出 思路 小技巧(拿小本本记下来) round #618 div2 C(文末有技巧) 这是题目链接->链接 题目: 原题 ...
- odoo开发教程四:onchange、唯一性约束
一:onchange机制[onchange=前端js函数!可以实现前端实时更新以及修改验证] onchange机制:不需要保存数据到数据库就可以实时更新用户界面上的显示. @api.onchange( ...