1 select的作用
一个select语句用来选择哪个case中的发送或接收操作可以被立即执行。
它类似于switch语句,但是它的case涉及到channel有关的I/O操作。
select就是用来监听和channel有关的IO操作,当 IO 操作发生时,触发相应的动作。
单Go程下只能监控一个channel的状态,
使用select可以io多路复用, 同时监控多个channel
注意:
- 每个case 语句都必须是一个面向channel的操作
- select只会执行其中一条, 如果没有一种case能执行, 则循环判断
- 如果有一个或多个IO操作可以完成,则Go运行时系统会随机的选择一个执行
- 否则如果有default分支,则执行default分支语句
- 如果连default都没有,则select语句会一直阻塞,直到至少有一个IO操作可以进行
- 如果case里有break, 则只会跳出select语句, 而不会跳出外面的for循环
2 案例
(1) 多通道选择
package main
import (
"fmt"
)
func main() {
c := make(chan int)
quit := make(chan int)
go func() {
for i := 0; i < 5; i++ {
fmt.Println("子程收到:", <-c)
}
fmt.Println("子程发送:退出")
quit <- 0
}()
for {
select {
case c <- 1: // 如果成功向c写入2
fmt.Println("写入1")
case c <- 2: // 如果成功向c写入2
fmt.Println("写入2")
case <-quit: // 如果成功从quit读取出数据
fmt.Println("收到退出")
return
default: // 如果上面都没有成功, 就进入default
fmt.Println("default")
}
}
}
(2) 超时控制
select {
case ret := <-retCh:
fmt.Println(ret)
case <-time.After(time.Second):
fmt.Println("time out")
}