这段代码在许多goroutine中并发运行,下面的代码是从生产环境代码中提取的关键和相关部分:
func check() {
.......check condition......
//skipEnsure and skipNative will not both false here
var wg sync.WaitGroup
if !skipEnsure {
wg.Add(1)
go func(wg *sync.WaitGroup) {
defer wg.Done()
dosomething1()
}(&wg)
}
if !skipNative {
wg.Add(1)
go func(wg *sync.WaitGroup) {
defer wg.Done()
dosomething2()
}(&wg)
}
wg.Wait() //panic here
}
func worker() {
......
go check()
}
func main() {
for i:=0;i<32;i++ {
go worker()
}
ch := make(chan any, 0)
<-ch
}
字符串
当WaitGroup是一个全局变量时,我可以重现这个问题,但不能在提供的代码中重现。在生产环境中运行一段时间后,它可能会导致死机。
1条答案
按热度按时间wqsoz72f1#
如果我理解正确的话,代码看起来像这样:
WaitGroup不是为这种用途设计的。何时调用wg.add和wg.wait并不明显。如果您尝试使用数据竞争检测器运行它,您可以看到如下内容:
字符串
你可以为每个goroutine使用自己的WaitGroup(如你的例子)。我想不出有什么理由反对它。例如,下面的代码可以很好地工作,没有任何数据竞争:
型