在线文档  >   Golang练习   >   超时处理

Go 超时 ,对于连接到外部资源,或需要限制执行时间的程序非常重要。
在Go中通过通道和select实现超时非常容易和优雅。

package main

import (
    "fmt"
    "time"
)

func main() {

    // 以下面示例为例,假设我们正在执行一个外部调用,并在2秒后在通道`c1`上返回结果。
    // 请注意,通道是有缓冲的,因此goroutine中的发送是非阻塞的。
    // 这是一种常见的模式,以防通道永远不会被读取而导致goroutine泄漏。
    c1 := make(chan string, 1)
    go func() {
        time.Sleep(2 * time.Second)
        c1 <- "result 1"
    }()

    // 这是使用`select`实现超时的方法。
   // `res := <-c1`等待结果,`<-time.After`等待在1s后发送一个值。
   // 由于`select` 默认处理第一个准备好的接收操作,
   // 如果操作耗费超过允许的1s,那么就会选择超时情况。
    select {
    case res := <-c1:
        fmt.Println(res)
    case <-time.After(1 * time.Second):
        fmt.Println("timeout 1")
    }

    // 如果我们允许更长的3秒超时,则从`c2`接收将成功,并打印出结果。
    c2 := make(chan string, 1)
    go func() {
        time.Sleep(2 * time.Second)
        c2 <- "result 2"
    }()
    select {
    case res := <-c2:
        fmt.Println(res)
    case <-time.After(3 * time.Second):
        fmt.Println("timeout 2")
    }
}

运行结果如下:

$ go run timeouts.go 
timeout 1
result 2```go
$ go run timeouts.go 
timeout 1
result 2

运行此程序将显示第一个操作超时和第二个成功。