我有以下代码作为测试的一部分:
expected := 10
var wg sync.WaitGroup
for i := 0; i < expected; i++ {
go func(wg *sync.WaitGroup) {
wg.Add(1)
defer wg.Done()
// do something
}(&wg)
}
wg.Wait()
令我惊讶的是,我panic: Fail in goroutine after TestReadWrite has completed
在运行“go test”时得到了。当使用“go test -race”运行时,我并没有感到恐慌,但后来测试失败了。在这两种情况下,尽管有 wg.Wait(),goroutine 都没有完成执行。
我进行了以下更改,现在测试按预期工作:
expected := 10
var wg sync.WaitGroup
wg.Add(expected)
for i := 0; i < expected; i++ {
go func(wg *sync.WaitGroup) {
defer wg.Done()
// do something
}(&wg)
}
wg.Wait()
我的疑问是:
- 到目前为止,我看到的很多代码都
wg.Add(1)
在 goroutine 中。为什么在这种特定情况下会出现意外行为?这里似乎发生的是,一些 goroutine 似乎已经完成运行,并且在其他 goroutine 开始运行之前就通过了 wg.Wait()。在 goroutine 中使用 wg.Add(1) 是否危险/要避免?如果这通常不是问题,那么究竟是什么导致了这里的问题? - 是否添加
wg.Add(expected)
了解决此问题的正确方法?