(golang select) Golang关键字select的常用用法总结
select
是 Go 语言中的一个控制结构,用于处理同步、异步IO操作时的阻塞选择问题。select
可以监听多个 channel 的数据流动,根据 case 中的 channel 是否可以进行读写来决定执行哪个 case,它的用法有些类似于 switch 语句,但是用于 channel 的选择。
下面将详细介绍 select
的基本用法,以及如何在代码中使用它。
基本用法
select
语句中的每个 case
分支都必须是一个通信操作,要么是发送操作,要么是接收操作。
select {
case x := <-ch1:
// 当 ch1 接收到数据时执行
fmt.Println("Received on ch1:", x)
case ch2 <- y:
// 当 ch2 可以发送数据时执行
fmt.Println("Sent on ch2", y)
default:
// 如果以上都没准备好,执行 default 分支
fmt.Println("Neither channel is ready")
}
使用 select
避免阻塞
// 假设有两个 channel
ch1 := make(chan string)
ch2 := make(chan string)
// 启动一个 goroutine 向 ch1 发送数据
go func() {
time.Sleep(time.Second * 1)
ch1 <- "from ch1"
}()
// 启动另一个 goroutine 向 ch2 发送数据
go func() {
time.Sleep(time.Second * 2)
ch2 <- "from ch2"
}()
// 使用 select 监听两个 channel
for i := 0; i < 2; i++ {
select {
case msg := <-ch1:
fmt.Println(msg)
case msg := <-ch2:
fmt.Println(msg)
}
}
这个例子中,select
将在 ch1
或 ch2
准备好接收数据时执行相关分支。由于使用了 for 循环,它将获取两个 channels 中的消息。
select
和超时
可以使用 select
语句来设置一个超时时间,以避免永久等待 channel 操作:
ch := make(chan string)
go func() {
time.Sleep(time.Second * 5)
ch <- "data"
}()
select {
case data := <-ch:
fmt.Println("Received:", data)
case <-time.After(time.Second * 3):
fmt.Println("Timeout!")
}
在这个例子中,如果 channel ch
在 3 秒内没有接收到数据,会执行 case <-time.After(time.Second * 3):
分支,打印出 “Timeout!”。
注意事项
- 如果多个
case
同时准备好,select
会随机选择一个执行。 - 如果
select
中没有default
分支,且所有case
都未准备好,那么select
会阻塞,直至至少有一个case
可执行。 default
分支通常用于非阻塞的发送/接收操作,以避免select
造成的阻塞。
这样就介绍了 select
在 Go 中的常见用法,以及基本的代码实现。在实际的开发中,根据具体的需求,select
可以很好地帮助你控制多个 channel 的同步和通信。
(亿图图示破解版安装教程) 亿图Edraw Max安装教程 亿图Edraw Max安装和基本使用指南 全网首发(图文详解1)
(shell -d) shell 脚本中的 ‘-f’ 和 ‘-d’ 是什么意思 文件检测的使用 f 和 d 选项 全网首发(图文详解1)