在go语言中,select语句就是用来监听和channel有关的I/O操作的,当I/O操作发生时候,就会触发相应的case动作。
- go语言中的select只能应用于channel操作,即可以用于channel的数据接收,也可以用于数据的发送。
- 如果select的多个分支都满足条件,会随机选择其中满足条件的一个分支进行执行。无法保证执行的顺序。
func slectUse() {
ch1 := make(chan int, 2)
ch2 := make(chan int, 2)
ch1 <- 1
ch2 <- 2
select {
case x := <-ch1:
fmt.Println("执行case1,输出ch1的值", x)
case i := <-ch2:
fmt.Println("执行case2,输出ch2的值", i)
}
}
func main() {
for i := 0; i < 2; i++ {
slectUse()
}
}
执行的结果如下:
- 如果不设置default条件,当没有channel操作发生时,select语句会一直阻塞,有default条件则在没有channel相关操作触发的时候会执行default语句。
func slectUse() {
ch1 := make(chan int, 2)
ch2 := make(chan int, 2)
//ch1 <- 1
//ch2 <- 2
select {
case x := <-ch1:
fmt.Println("执行case1,输出ch1的值", x)
case i := <-ch2:
fmt.Println("执行case2,输出ch2的值", i)
}
}
执行的结果如下:一直阻塞
4. 对于空的select语句会引起死锁(阻塞)
5. 对于在for不断循环的select语句,不宜使用default语句,否则会一直循环的执行default语句,引起cpu占用过高的现象。
func slectUse() {
ch1 := make(chan int, 2)
ch2 := make(chan int, 2)
//ch1 <- 1
//ch2 <- 2
for true {
select {
case x := <-ch1:
fmt.Println("执行case1,输出ch1的值", x)
case i := <-ch2:
fmt.Println("执行case2,输出ch2的值", i)
default:
fmt.Println("没有channel触发")
}
}
}