2 回答
TA贡献1816条经验 获得超6个赞
根据文档 -
等待组等待一组大流子体完成。主戈鲁丁调用 Add 以设置要等待的戈鲁廷数。然后,每个戈鲁丁都会运行并在完成后调用“完成”。同时,等待可用于阻止,直到所有戈鲁丁都完成。
所以必须由一个戈鲁廷来调用,它正在引发其他的戈鲁廷,在你的情况下是戈鲁廷。Add()main
在第一个代码片段中,您正在调用其他戈鲁廷内部,而不是导致问题的主要戈鲁廷 -Add()
expected := 10
var wg sync.WaitGroup
for i := 0; i < expected; i++ {
go func(wg *sync.WaitGroup) {
wg.Add(1) // Do not call Add() here
defer wg.Done()
// do something
}(&wg)
}
wg.Wait()
第二个片段正在工作,因为你正在调用戈鲁廷 -Add()main
expected := 10
var wg sync.WaitGroup
wg.Add(expected) // Okay
for i := 0; i < expected; i++ {
go func(wg *sync.WaitGroup) {
defer wg.Done()
// do something
}(&wg)
}
wg.Wait()
正在添加工作组。添加(预期)解决此问题的正确方法?
您也可以在 for 循环中调用 -wg.Add(1)
expected := 10
var wg sync.WaitGroup
for i := 0; i < expected; i++ {
wg.Add(1) // Okay
go func(wg *sync.WaitGroup) {
defer wg.Done()
// do something
}(&wg)
}
wg.Wait()
TA贡献1942条经验 获得超3个赞
你的第一种方法恐慌 coz (WaitGroup.Add):
“添加”将增量(可能为负数)添加到“等待组”计数器。如果计数器变为零,则释放在 Wait 上阻止的所有大猩猩。如果计数器变为负数,则添加恐慌。
...
...
通常,这意味着对 Add 的调用应在创建 goroutine 或其他要等待的事件的语句之前执行
当在代码末尾调用 Wait() 时,可能没有一个 goroutine 开始执行 - 因此 WaitGroup 中保存的值为 0。然后,当您的 go 例程执行时,调用 go 例程已经发布。这将导致意想不到的行为,在您的案例中引起恐慌。也许你在那里使用了调用 go 例程中的值。
你的第二种方法绝对没问题。您也可以在环路内调用 - 但在块外.Add(1)
go func
- 2 回答
- 0 关注
- 76 浏览
添加回答
举报