在golang语言中,select语句 就是用来监听和channel有关的IO操作,当IO操作发生时,触发相应的case动作。有了 select语句,可以实现 main主线程 与 goroutine线程 之间的互动。
select {
case <-ch1 : // 检测有没有数据可读
// 一旦成功读取到数据,则进行该case处理语句
case ch2 <- 1 : // 检测有没有数据可写
// 一旦成功向ch2写入数据,则进行该case处理语句
default:
// 如果以上都没有符合条件,那么进入default处理流程
}
下面看几个简单的例子:
func SelectTest() {
//=============case1===================
cz := make(chan int)
rand.Seed(time.Now().Unix())
go func() {
time.Sleep(time.Second * time.Duration(rand.Intn(10)))
cz <- 1 //随机时间往管道里写入值
}()
go func() {
time.Sleep(time.Second * time.Duration(rand.Intn(10)))
cz <- 2
}()
select {
case num := <-cz:
if num == 1 {
fmt.Println("case1:", num)
} else {
//其他业务逻辑
fmt.Println("case1:", num)
}
case <-time.Tick(time.Second * 5): //设置超时
fmt.Println("timeout")
//当需要阻塞等待时,可以不写default语句,但必须要设置超时时间,以防止信道里始终没有接收到数据而发生超时
//default:
// fmt.Println("default")
}
//=============case2===================
c1 := make(chan string, 1)
c2 := make(chan string, 1)
go func() {
time.Sleep(time.Second * 1)
c1 <- "c1"
}()
go func() {
time.Sleep(time.Second * 2)
c2 <- "c2"
}()
select {
case msg1 := <-c1: //每个case执行具有随机性
fmt.Println(msg1)
case msg2 := <-c2:
fmt.Println(msg2)
//default:
// fmt.Println("no data!")
}
//=============case3===================
c := time.Tick(5 * time.Second)
now := time.Now()
end := now.Add(time.Hour)
isRun := true
rand.Seed(time.Now().Unix())
for now.Before(end) && isRun {
select {
case <-c:
isRun = rand.Intn(100) > 50
}
now = time.Now()
}
fmt.Println("end")
}