1、select说明

select 是 Go 中的一个控制结构,每个 case 必须是一个通信操作,要么是发送要么是接收。 select 随机执行一个可运行的 case。如果没有 case 可运行,它将阻塞,直到有 case 可运行。一个默认的子句(default:子句)应该总是可运行的。

selectchannel
select{
case <- ch1:
// do something
case i := <- ch2
// use i do something
default:
// ...
}

2、超时处理

golang的select与channel配合使用进行超时处理。channel必须是有缓冲channel。

select用于等待一个或者多个channel的输出。

应用场景:主goroutine等待子goroutine完成,但是子goroutine无限运行,导致主goroutine会一直等待下去。而主线程想假如超过了一定的时没有返回的话,进行超时判断然后继续运行下去。

3、示例

package main

import (
	"time"
	"fmt"
)

var chs chan int = make(chan int, 1) //创建通道chs

func write(){
	time.Sleep(3 * time.Second)
	chs <- 1    //chs中写入1
}

func read() {
	select {
	case ch1 := <-chs:    //将chs中的data写到ch1
		fmt.Println(ch1)
		return
	case <-time.After(4*time.Second):    //超时判断
		fmt.Println("read time out")
		return
	}
}

func main() {
	go write() //启动新的协程,在其中执行了3秒的sleep,并执行其他操作,可以多起几个协程,试试效果
	read()     //主协程会根据select语句进行判断执行
}

//以上代码结果:
[root@localhost]# go run main.go
1
//如果将time.After中改为1*time.Second,则输出为:
[root@localhost]# go run main.go
read time out

原因在于,select会由上到下判断哪个case可以执行。