在下面的 Go 代码中,变量 v 通常小于预期,因为wg.Add() 的位置不正确。
<code class="go">var wg sync.WaitGroup var v int32 = 0 for i := 0; i < 100; i++ { go func() { wg.Add(1) // Wrong place atomic.AddInt32(&v, 1) wg.Done() } } wg.Wait() fmt.Println(v)</code>
wg.Add() 应始终在启动相应的 Goroutine 之前调用,以确保主 Goroutine 阻塞,直到所有goroutine 已执行 wg.Done().
<code class="go">var wg sync.WaitGroup var v int32 = 0 for i := 0; i < 100; i++ { wg.Add(1) go func() { atomic.AddInt32(&v, 1) wg.Done() } } wg.Wait() fmt.Println(v)</code>
当 wg.Add() 放在 goroutine 内部时,不能保证主 goroutine 会阻塞,直到所有 goroutine 完成。这是因为 goroutine 是并发运行的,执行顺序是不确定的。
通过将 wg.Add() 放在 goroutine 之前,我们可以确保主 goroutine 在到达之前调用 wg.Add() 100 次wg.Wait().这可以确保主 goroutine 阻塞,直到所有 100 个 goroutine 都调用了 wg.Done(),从而导致 v 始终等于 100。
使用sync.WaitGroup 时,请遵循这些指南:
以上是为什么 wg.Add() 放置对于保证 Go 中的同步至关重要?的详细内容。更多信息请关注PHP中文网其他相关文章!