這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
早期的select函數是用來監控一系列的檔案控制代碼,一旦其中一個檔案控制代碼發生IO操作,該select調用就會被返回。golang在語言層級直接支援select,用於處理非同步IO問題。
select用法同switch類似,如下:
timeout := make (chan bool, 1)
ch := make(chan int) select { case <-ch: case <-timeout: fmt.Println("timeout!") default: fmt.Println("default case is running") }
可以看出,ch初始化後,case1讀取失敗,timeout同樣失敗,因為channel中無資料,直接跳至default執行並返回。
注意,如果沒有default,select 會一直等待等到某個 case 陳述式完成, 也就是等到成功從 ch 或者 timeout 中讀到資料,否則一直阻塞。
基於這種機制,可以使用select實現channel讀取逾時的機制
package main import ( "fmt" "time" ) func main() { timeout := make(chan bool, 1) go func() { time.Sleep(3e9) // sleep 3 seconds timeout <- true }() ch := make(chan int) select { case <-ch: case <-timeout: fmt.Println("timeout!") } }
注意這裡一定不能用default,否則3s逾時還未到直接執行default,case2便不會執行,逾時機制便不會實現。timeout會在3s逾時後讀取到資料。
使用select判斷channel是否存滿
ch1 := make(chan int, 1) ch2 := make(chan int, 1) select { case <-ch1: fmt.Println("ch1 pop one element") case <-ch2: fmt.Println("ch2 pop one element") default: fmt.Println("default") }
如果case1、case2均未執行,則說明ch1&ch2已滿,over.....