将超时分配给WaitGroup.Wait()的惯用方式是什么?
我要这样做的原因是为了保护我的“调度员”免于永远等待错误的“工人”。这就引出了一些哲学问题(例如,一旦有错误的工作人员,系统如何才能可靠地继续?),但我认为这超出了这个问题的范围。
我将提供一个答案。现在,我已将其写下来,它似乎还不错,但仍然感觉比应有的更复杂。我想知道是否有一些更简单,更惯用的方法,甚至是不使用WaitGroups的替代方法。
助教。
通常,您在下面发布的解决方案都可以得到最好的解决方案。改善的几个技巧:
defer
WaitGroup
select
timeout := time.Second
timeout := 2 * time.Second
time.Second
time.Duration
2
我还将创建包装此功能的帮助程序/实用程序功能。请注意,WaitGroup必须将其作为指针传递,否则副本将不会“通知” WaitGroup.Done()调用。就像是:
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上尝试一下。