返回介绍

10.3.2 方式2

发布于 2024-08-14 12:50:32 字数 5803 浏览 0 评论 0 收藏 0

第二个技巧的源码保存在 timeOut2.go 中,并分为五部分来介绍。这次,超时时间作为命令行参数提供给程序。

timeOut2.go 的第一部分如下:

package main

import (
    "fmt"
    "os"
    "strconv"
    "sync"
    "time"
)

timeOut2.go 的第二段代码如下:

func timeout(w *sync.WaitGroup, t time.Duration) bool {
    temp := make(chan int)
    go func() {
        time.Sleep(5 * time.Second)
        defer close(temp)
        w.Wait()
    }()

    select {
        case <-temp:
            return false
        case <-time.After(t):
            return true
    }
}

上面的代码里,time.After() 调用使用的时间周期是 timeout() 函数的一个参数,就是说它可变。再次,select 块实现了超时逻辑。另外,w.Wait() 调用使 timeout() 函数无期限的等待一个匹配的 sync.Done() 函数来结束。当 w.Wait() 调用返回,select 表达式的第一个分支就会执行。

timeOut2.go 的第三段代码如下:

func main() {
    arguments := os.Args
    if len(arguments) != 2 {
        fmt.Println("Need a time duration!")
        return
    }

    var w sync.WaitGroup
    w.Add(1)
    t, err := strconv.Atoi(arguments[1])
    if err != nil {
        fmt.Println(err)
        return
    }

timeOut2.go 的第四部分如下:

    duration := time.Duration(int32(t)) * time.Millisecond
    fmt.Printf("Timeout period is %s\n", duration)

    if timeout(&w, duration) {
        fmt.Println("Timed out!")
    } else {
        fmt.Println("OK!")
    }

time.Duration() 函数转换一个整数值给一个之后使用到的 time.Duration 变量。

timeOut2.go 的其余代码如下:

    w.Done()
    if timeout(&w, duration) {
        fmt.Println("Timed out!")
    } else {
        fmt.Println("OK!")
    }
}

一旦 w.Done() 调用执行,之前的 timeout() 函数将返回。然而第二次调用 timeout() 没有要等待的 sync.Done() 语句。

执行 timeOut2.go 产生如下输出:

$go run timeOut2.go 10000
Timeout period is 10s
Timed out!
OK!

执行 timeOut2.go 的超时周期比匿名 goroutine 的 time.Sleep(5 * time.Second) 长。然而,没有必要的 w.Done() 调用,匿名 goroutine 不能返回因为 time.After() 调用先结束了,所以第一个 if 表达式的 timeout() 函数返回 true。第二个 if 表达式,匿名函数不必等待,因为 time.Sleep(5 * time.Second) 将先于 time.After(t) 结束,所以 timeout() 函数返回 false:

$go run timeOut2.go 100
Timeout period is 100ms
Timed out!
Timed out!

然而,第二次执行,这个超时周期太短了,所以这两个 timeout() 的执行都没有足够的时间完成,因此都超时了。

所以,当定义一个超时周期时,确保您选择了一个恰当的值,否则您的结果可能不是您期望的那样。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文