這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
簡單的說下select是幹什麼的?
select用來讓我們的程式監視多個檔案控制代碼(file descriptor)的狀態變化的處理機制。當你發起一些阻塞的請求後,你可以使用select機制輪訓掃描fd,直到被監視的檔案控制代碼有某一個或多個發生了狀態改變。
該文章寫的有些亂,歡迎來噴 ! 另外文章後續不斷更新中,請到原文地址查看更新。
http://xiaorui.cc/?p=2997
本來只是想說下select,但又忍不住廢話下說下epoll的處理流程:
我們可以把要監控讀寫的檔案交給核心(epoll_add),而核心通過中斷的方式得知事件通知. 這要比select好不少.設定你關心的事件(epoll_ctl),比如讀事件.然後等(epoll_wait),此時,如果沒有哪個檔案有你關心的事件,則休眠,直到有事件,被喚醒,然後返回那些事件.Epoll的優勢在於,由接收資料的OS來負責通知你有資料可以操作,因為OS是知道什麼時候有資料的。select 跟golang有啥關聯? 首先我們通過上面的介紹得知,select是通過線性掃描的方式監視檔案描述符是否有變動. channnel在系統層面來說也是個檔案描述符。 在golang裡我們可以使用goroutine並發執行任務,接著使用select來監視每個任務的channel情況. 但如果這幾個任務都長時間沒有回複channel資訊,如果我們又有逾時timeout需求,那麼我們可以使用起一個goroutine,這個goroutine任務邏輯啟動sleep,等sleep之後回複channel訊號。
說了這麼多沒用的,才聊到咱們golang goroutine select正事….
Python#http://xiaorui.ccpackage mainimport ( "fmt" "time")func main() { timeout := make(chan bool, 1) go func() { time.Sleep(3 * time.Second) // sleep 3 second timeout <- true }() ch := make(chan int) select { case <-ch: case <-timeout: fmt.Println("task is timeout!") }}
| 1234567891011121314151617181920212223 |
#http://xiaorui.cc package main import ( "fmt" "time") func main() { timeout := make(chan bool, 1) go func() { time.Sleep(3 * time.Second) // sleep 3 second timeout <- true }() ch := make(chan int) select { case <-ch: case <-timeout: fmt.Println("task is timeout!") }} |
上面golang那段代碼運行後的結果是:
Pythontask is timeout!