目录
select
语句
select
语句在Go语言中有着广泛的用途,它是一种用于在多个通信操作中进行选择的控制结构。以下是select
语句的几个常见用途:
- 多通道选择:
select
语句可以同时监听多个通道的读写操作,并选择其中一个可执行的操作进行处理。通过select
语句,可以实现并发程序中的多路复用,避免阻塞等待。这是select
语句最常见的用法之一。
select {
case <-channel1:
// 处理channel1接收操作
case data := <-channel2:
// 处理channel2接收操作
case channel3 <- value:
// 处理channel3发送操作
default:
// 当没有任何通信可用时执行该分支
}
- 超时处理:
select
语句可以与time.After
函数结合使用,实现对操作的超时控制。通过在select
语句中添加一个定时器通道,可以在指定时间内等待操作的完成,超过设置的时间则执行超时处理。
timeout := time.After(5 * time.Second)
select {
case result := <-dataChannel:
// 处理接收到的数据
case <-timeout:
// 执行超时处理
}
- 阻塞与非阻塞选择:
select
语句可以配合default
分支实现非阻塞的通信操作。当没有任何通信可用时,select
语句会立即执行default
分支中的代码,而不会阻塞等待。
select {
case data := <-channel:
// 处理接收到的数据
default:
// 没有任何通信可用时立即执行该分支
}
- 程序退出控制:
select
语句可以与特殊的退出通道结合使用,实现对程序退出的控制。通过监听退出通道,可以在需要结束程序时触发退出操作。
done := make(chan bool)
select {
case <-interruptChannel:
// 处理中断事件
done <- true
case <-terminateChannel:
// 处理终止事件
done <- true
case <-done:
// 接收到退出信号,结束程序
}
- select可以同时监听一个或多个channel,直到其中一个channel ready
package main
import (
"fmt"
"time"
)
func test1(ch chan string) {
time.Sleep(time.Second * 5)
ch <- "test1"
}
func test2(ch chan string) {
time.Sleep(time.Second * 2)
ch <- "test2"
}
func main() {
// 2个管道
output1 := make(chan string)
output2 := make(chan string)
// 跑2个子协程,写数据
go test1(output1)
go test2(output2)
// 用select监控
select {
case s1 := <-output1:
fmt.Println("s1=", s1)
case s2 := <-output2:
fmt.Println("s2=", s2)
}
}
- 如果多个channel同时ready,则随机选择一个执行
package main
import (
"fmt"
)
func main() {
// 创建2个管道
int_chan := make(chan int, 1)
string_chan := make(chan string, 1)
go func() {
//time.Sleep(2 * time.Second)
int_chan <- 1
}()
go func() {
string_chan <- "hello"
}()
select {
case value := <-int_chan:
fmt.Println("int:", value)
case value := <-string_chan:
fmt.Println("string:", value)
}
fmt.Println("main结束")
}