Golang利用select實現超時機制

OldBoy~發表於2018-09-22

所謂超時,比如上網瀏覽一些安全的網站,如果幾分鐘之後不做操作,那麼就會讓你重新登入。
就所謂有時候出現goroutine阻塞的情況,那麼我們如何避免整個程式進入阻塞情況,這時候就可以用select來設定超時

package main

import (
    "fmt"
    "time"
)

func main() {
    ch := make(chan int)
    quit := make(chan bool)

    //新開一個協程
    go func() {
        for {
            select {
            case num := <-ch:  //如果有資料,下面列印。但是有可能ch一直沒資料
                fmt.Println("num = ", num)
            case <-time.After(3 * time.Second): //上面的ch如果一直沒資料會阻塞,那麼select也會檢測其他case條件,檢測到後3秒超時
                fmt.Println("超時")
                quit <- true  //寫入
            }
        }

    }() //別忘了()

    for i := 0; i < 5; i++ {
        ch <- i
        time.Sleep(time.Second)
    }

    <-quit //這裡暫時阻塞,直到可讀
    fmt.Println("程式結束")

}
//這裡注意觀察列印過程
num =  0
num =  1
num =  2
num =  3
num =  4
超時
程式結束

補充程式碼

//防止讀取超時
select { 
    case <- time.After(time.Second*2): 
        println("read channel timeout") 
    case i := <- ch: 
        println(i) 
} 

//防止寫入超時
select { 
    case <- time.After(time.Second *2): 
        println("write channel timeout") 
    case ch <- "hello": 
        println("write ok") 
}

 

相關文章