首页  >  文章  >  后端开发  >  如何在 Go 中为 WaitGroup.Wait() 添加超时?

如何在 Go 中为 WaitGroup.Wait() 添加超时?

Susan Sarandon
Susan Sarandon原创
2024-11-21 06:03:09733浏览

How to Add a Timeout to WaitGroup.Wait() in Go?

厌倦了永远的等待?向 WaitGroup.Wait() 添加超时

当您使用 WaitGroup.Wait() 来同步 Goroutines 并确保它们完成执行时,您有时可能希望能够在特定持续时间后终止等待。这可以防止您的系统无休止地依赖可能永远无法完成任务的错误工作人员。

定时等待组的实用解决方案

实现超时的一种方法是利用goroutine、通道和时间包的组合。这个想法是创建一个通道,在所有 goroutine 完成后接收信号。同时,定时器被初始化为所需的超时持续时间。 select 语句用于监视通道和计时器:

import (
    "sync"
    "time"
)

func task(wg *sync.WaitGroup) {
    // Perform some task...
    time.Sleep(time.Second * 2)
    wg.Done()
}

func main() {
    var wg sync.WaitGroup
    wg.Add(2)
    go task(&wg)
    go task(&wg)

    ch := make(chan struct{})
    defer close(ch)

    go func() {
        defer wg.Done()
        wg.Wait()
        close(ch)
    }()

    timeout := 5*time.Second

    select {
    case <-ch:
        fmt.Println("All jobs completed within timeout.")
    case <-time.After(timeout):
        fmt.Println("Timeout reached, not all jobs completed.")
    }
}

使用辅助函数简化超时

为了提供更方便和可重用的方法,考虑创建一个封装此功能的辅助函数:

func waitTimeout(wg *sync.WaitGroup, timeout time.Duration) bool {
    c := make(chan struct{})
    go func() {
        defer close(c)
        wg.Wait()
    }()
    select {
    case <-c:
        return false
    case <-time.After(timeout):
        return true
    }
}

此辅助函数接受 WaitGroup 和所需的超时持续时间,并返回等待是否超出指定限制。

辅助函数的使用

使用辅助函数非常简单:

if waitTimeout(&wg, 5*time.Second) {
    fmt.Println("Timeout reached waiting for wait group.")
}

在此示例中,如果等待组花费超过 5 秒的时间,waitTimeout 函数将返回 true完成,表明发生超时。

以上是如何在 Go 中为 WaitGroup.Wait() 添加超时?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn