select
参考 https://draveness.me/golang/docs/part2-foundation/ch05-keyword/golang-select/
Go 语言中的 select 关键字能够让 Goroutine 同时等待多个 Channel 的可读或者可写,在多个 Channel 发生状态改变之前,select 会一直阻塞当前线程或者 Goroutine。
当我们在 Go 语言中使用 select 控制结构时,会遇到两个有趣的现象:
- select 能在 Channel 上进行非阻塞的收发操作;
- select 在遇到多个 Channel 同时响应时会随机挑选 case 执行;
阻塞的情况
func fibonacci(c, quit chan int) {
x, y := 0, 1
for {
select {
case c <- x:
x, y = y, x+y
case <-quit:
fmt.Println("quit")
return
}
}
} 非阻塞的实际情况
errCh := make(chan error, len(tasks)
wg := sync.WaitGroup{}
wg.Add(len(tasks))
for i := range tasks {
go func() {
defer wg.Done()
if err := tasks[i].Run(); err != nil {
errCh <- err
}
}()
}
wg.Wait()
select {
case err := <-errCh:
return err
default:
return nil
} 在上面这段代码中,我们不关心到底多少个任务执行失败了,只关心是否存在返回错误的任务,最后的 select 语句就能很好地完成这个任务。

京公网安备 11010502036488号