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