💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
### select作用 select关键词用于监听通道数据的流动,用法类似于switch ``` select { case <-chan1: //如果成功读取到chan1的数据,就执行该case语句 case <-chan2: //如果成功读取到chan2的数据,就执行该case语句 ... default: //如果上面case都没有执行成功,则执行该default语句 } ``` ``` package main import ( "fmt" "time" ) func main() { // 创建一个通道 ch := make(chan int) go func() { for i := 0; i < 3; i++ { // i发送到通道 ch <- i } }() for { // 监听通道的数据 select { // msg是读取通道的内容 case msg := <-ch: fmt.Println(msg) default: //如果没有case可以执行 就会堵塞 一直执行default。进程会从select后恢复执行 // 如果没有 default语句,那么就会一直堵塞,直到有通道可以进行下去 time.Sleep(time.Second) } fmt.Println("到这会恢复") } } ``` ### 超时 有时候协程出现堵塞,为避免长时间堵塞,可以使用select来实现堵塞机制 ``` package main import ( "fmt" "time" ) func main() { // 创建一个通道传递 for循环的i ch := make(chan int) // 接收bool done := make(chan bool) go func() { for { select { // val取出通道ch里面的值 case val := <-ch: fmt.Println(val) case <-time.After(time.Second * 3): fmt.Println("已经超时3秒") // true发送给通道done done <- true } } }() for i := 0; i < 10; i++ { // i发送个通道ch ch <- i } // 取通道 done 里面的值 //<-done fmt.Println(<-done) fmt.Println("程序终止") } ``` ### 死锁 流出无流入,流入无流出,都会造成死锁 ``` package main func main() { ch := make(chan int) <-ch //堵塞main gotoutine,通信ch被锁 } ``` ``` package main func main() { select {} } ``` ``` fatal error: all goroutines are asleep - deadlock! ```