select
-
规则
select 和 IO 复用中的sleect 差不多一个思想,都是想通过多路复用提高效率。
其满足以下特性:-
如果有1个 case 语句满足,那么就执行这一个case
func main() { ch := make(chan int, 1) select { case ch <-1: fmt.Println("ch<-") default: fmt.Println("default") } } // 输出: ch<-
-
如果多个case 同时满足的情况,会随机选择一个case
func main() { ch1 := make(chan int, 1) ch2 := make(chan int, 1) select { case ch1 <-1: fmt.Println("ch1<-") case ch2 <-1: fmt.Println("ch2<-") default: fmt.Println("default") } } // 输出:多次运行,既有输出 ch2<-,也有输出 ch1<-
-
select存在default的话,在case不命中的情况下,会直接进入default分支处理
func main() { timeout := time.After(time.Second * 100) select { case <-timeout: fmt.Println("timeout") default: fmt.Println("default") } fmt.Println("select finish") for { } } // 输出: default select finish
-
如果没有 default,那么 代码块会被阻塞,直到有一个 case 通过;否则一直阻塞
func main() { timeout := time.After(time.Second * 10) fmt.Println("select start") select { case <-timeout: fmt.Println("timeout") } fmt.Println("select finish") for { } } // 输出 select start timeout // 这里超时10s输出 select finish
-
-
应用场景1:阻止main退出
func main() { ... select {} }
-
应用场景2:生成随机数序列
func main() { ch := make(chan int) go func() { for { select { case ch <- 1: case ch <- 2: case ch <- 3: case ch <- 4: case ch <- 5: case ch <- 6: } } }() for v := range ch { fmt.Print(v, " ") } }
-
应用场景3:为处理设置超时时间
c1 := make(chan string) timeout := time.After(time.Second * 2) go func(c chan string) { defer fmt.Println("go end", time.Now()) for { select { case str1 := <-c: fmt.Println("chan c1 receive:", str1, time.Now()) case <-timeout: return } } }(c1) time.Sleep(time.Second * 10)
网友评论