Go超時(timeouts)範例


超時對於連線到外部資源或在不需要繫結執行時間的程式很重要。在Go程式設計中由於使用了通道和選擇(select),實現超時是容易和優雅的。
在這個範例中,假設正在執行一個外部呼叫,2秒後在通道c1上返回其結果。

這裡是 select 實現超時。 res:= <-c1等待結果和<-Time。等待在超時1秒後傳送一個值。 由於選擇繼續準備好第一個接收,如果操作超過允許的1秒,則將按超時情況處理。

如果允許更長的超時,如:3s,那麼從c2的接收將成功,這裡將會列印結果。

執行此程式顯示第一個操作超時和第二個操作超時。

使用此選擇超時模式需要通過通道傳達結果。這是一個好主意,因為其他重要的Go功能是基於渠道和Select。現在看看下面的兩個例子:計時器和ticker

所有的範例程式碼,都放在 F:\worksp\golang 目錄下。安裝Go程式設計環境請參考:/2/23/798.html

timeouts.go的完整程式碼如下所示 -

package main

import "time"
import "fmt"

func main() {

    // For our example, suppose we're executing an external
    // call that returns its result on a channel `c1`
    // after 2s.
    c1 := make(chan string, 1)
    go func() {
        time.Sleep(time.Second * 2)
        c1 <- "result 1"
    }()

    // Here's the `select` implementing a timeout.
    // `res := <-c1` awaits the result and `<-Time.After`
    // awaits a value to be sent after the timeout of
    // 1s. Since `select` proceeds with the first
    // receive that's ready, we'll take the timeout case
    // if the operation takes more than the allowed 1s.
    select {
    case res := <-c1:
        fmt.Println(res)
    case <-time.After(time.Second * 1):
        fmt.Println("timeout 1")
    }

    // If we allow a longer timeout of 3s, then the receive
    // from `c2` will succeed and we'll print the result.
    c2 := make(chan string, 1)
    go func() {
        time.Sleep(time.Second * 2)
        c2 <- "result 2"
    }()
    select {
    case res := <-c2:
        fmt.Println(res)
    case <-time.After(time.Second * 3):
        fmt.Println("timeout 2")
    }
}

執行上面程式碼,將得到以下輸出結果 -

F:\worksp\golang>go run timeouts.go
timeout 1
result 2