WaitGroup.Wait()的超时

将超时分配给WaitGroup.Wait()的惯用方式是什么?

我要这样做的原因是为了保护我的“调度员”免于永远等待错误的“工人”。这就引出了一些哲学问题(例如,一旦有错误的工作人员,系统如何才能可靠地继续?),但我认为这超出了这个问题的范围。

我将提供一个答案。现在,我已将其写下来,它似乎还不错,但仍然感觉比应有的更复杂。我想知道是否有一些更简单,更惯用的方法,甚至是不使用WaitGroups的替代方法。

助教。

回答:

通常,您在下面发布的解决方案都可以得到最好的解决方案。改善的几个技巧:

  • 或者,您可以关闭通道以完成信号,而不是在通道上发送值,关闭通道上的接收操作始终可以立即进行。
  • 并且最好使用defer语句来表示完成,即使函数突然终止,它也会被执行。
  • 同样,如果只有一个“作业”要等待,则可以完全省略,WaitGroup而仅在作业完成时发送一个值或关闭通道(在select语句中使用相同的通道)。
  • 指定持续1秒很简单,只要:timeout := time.Second。例如,指定2秒为:timeout := 2 * time.Second。您不需要转换,time.Second它已经是type了time.Duration,将其与未类型化的常量相乘,就像这样,2也会产生type的值time.Duration

我还将创建包装此功能的帮助程序/实用程序功能。请注意,WaitGroup必须将其作为指针传递,否则副本将不会“通知”

WaitGroup.Done()调用。就像是:

// waitTimeout waits for the waitgroup for the specified max timeout.

// Returns true if waiting timed out.

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 // completed normally

case <-time.After(timeout):

return true // timed out

}

}

使用它:

if waitTimeout(&wg, time.Second) {

fmt.Println("Timed out waiting for wait group")

} else {

fmt.Println("Wait group finished")

}

在Go Playground上尝试一下。

以上是 WaitGroup.Wait()的超时 的全部内容, 来源链接: utcz.com/qa/403354.html

回到顶部