Go Select语句的使用
select语句用于多个发送/接收通道操作中进行选择
- select语句会一直阻塞,直到发送/接收操作准备就绪
- 如果有多个通道操作准备完毕,select会随机的选取其中一个执行
select语法:
//select-case 和switch -case很相似,区别switch是顺序的,select不是顺序的
select{
case expression1:
code
case expression2:
code
default:
code
}
select应用
func SelectDemo() {
ch1 := make(chan string, 1)
ch2 := make(chan string, 1)
ch3 := make(chan string, 1)
ch1 <- "第一魂技"
ch2 <- "第二魂技"
ch3 <- "第三魂技"
select {
case message1 := <-ch1:
fmt.Println("ch1 received", message1)
case message2 := <-ch2:
fmt.Println("ch2 received", message2)
case message3 := <-ch3:
fmt.Println("ch3 received", message3)
default:
fmt.Println("No data received!")
}
}
func task1(ch chan string) {
time.Sleep(3 * time.Second)
ch <- "第一魂技"
}
func task2(ch chan string) {
time.Sleep(7 * time.Second)
ch <- "第2魂技"
}
func task3(ch chan string) {
time.Sleep(12 * time.Second)
ch <- "第3魂技"
}
func SelectDemo2() {
ch1 := make(chan string)
ch2 := make(chan string)
ch3 := make(chan string)
go task1(ch1)
go task2(ch2)
go task3(ch3)
select {
case message1 := <-ch1:
fmt.Println("ch1 received", message1)
case message2 := <-ch2:
fmt.Println("ch2 received", message2)
case message3 := <-ch3:
fmt.Println("ch3 received", message3)
//default:
// fmt.Println("No data received!")
}
}
func MockDeadLock() {
ch1 := make(chan string, 1)
ch2 := make(chan string, 1)
ch3 := make(chan string, 1)
select {
case message1 := <-ch1:
fmt.Println("ch1 received", message1)
case message2 := <-ch2:
fmt.Println("ch2 received", message2)
case message3 := <-ch3:
fmt.Println("ch3 received", message3)
//没有default会产生死锁 :fatal error: all goroutines are asleep - deadlock!
//default:
// fmt.Println("No data received!")
}
}
func EmptySelect() {
//发生死锁 :fatal error: all goroutines are asleep - deadlock!
select {}
}
func makeTimeOut(ch chan bool, t int) {
time.Sleep(time.Second * time.Duration(t))
ch <- true
}
func MockTimeOut() {
ch1 := make(chan string, 1)
ch2 := make(chan string, 1)
ch3 := make(chan string, 1)
timeOut := make(chan bool, 1)
go makeTimeOut(timeOut, 3)
select {
case message1 := <-ch1:
fmt.Println("ch1 received", message1)
case message2 := <-ch2:
fmt.Println("ch2 received", message2)
case message3 := <-ch3:
fmt.Println("ch3 received", message3)
case <-timeOut:
fmt.Println("time out exit!")
}
}
func SelectDemo3() {
ch := make(chan string, 2)
ch <- "我是谁,我在哪里,我要到哪里去"
select {
case ch <- "这问题太高深了":
fmt.Println(<-ch)
fmt.Println(<-ch)
default:
fmt.Println("no data!")
}
}