select實現斐波那契和超時機制
阿新 • • 發佈:2018-09-12
UNC package true sele for循環 break make con 選擇
package main import "fmt" func fib(ch chan <-int, quit <- chan bool){ x, y := 1, 1 for { //監聽channel的流動 select { case ch <- x: x, y = y, x+y case flag := <-quit: fmt.Println("flag=", flag) return } } } func main(){ ch := make(chan int) quit:=make(chan bool) go func() { for i:=0;i<8;i++{ num:=<-ch fmt.Println(num) /* 1 1 2 3 5 8 13 21 flag= true */ } quit <- true }() fib(ch, quit) } /* 分析一下代碼的邏輯 首先,對於select,是用來監聽管道的流動,多個case,那麽能執行,就執行哪個,如果都能執行會隨機選擇一個 對於case ch<-x,會先往ch裏面寫進去一個1。然後在子協程中num會接收到。此時x, y = y, x+y,然後繼續往ch裏面放入數據,然後num接收 當子協程裏的for循環執行完畢,那麽對於case ch<-x,即便往ch裏面放入數據,也沒辦法取了,因為循環結束了,無法執行num:= <- ch了 所以對於第一個case就卡在那裏了,會一直等待著有人把ch裏面的數據取走. 然後設置quit<-true,一開始第二個case flag:= <- quit裏面是沒有數據的,當我們設置值之後有數據了,那麽便可以取了,會取到flag=true 然後執行第二個case裏面的語句,return結束函數,從而結束程序。 需要註意的是:如果想跳出函數,在select裏面不要使用break,因為break也對select起作用,使用break跳出select,但並沒有跳出for循環,然後會又來執行select */
package main import ( "fmt" "time" ) func main() { ch := make(chan int) quit := make(chan bool) go func() { for { select { case num:=<-ch: fmt.Println(num) case <-time.After(time.Second * 3): fmt.Println("超時") quit <- true } } }() for i:=0;i<5;i++{ ch <- i } <-quit//主協程會卡在這裏,直到超時 fmt.Println("程序結束") } /* 0 1 2 3 4 超時 程序結束 */
select實現斐波那契和超時機制