1. 程式人生 > >select實現斐波那契和超時機制

select實現斐波那契和超時機制

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實現斐波那契和超時機制