首页 > 后端开发 > Golang > 正文

为什么 `wg.Add()` 的放置对于 Go 的 `sync.WaitGroup` 中的正确同步至关重要?

Linda Hamilton
发布: 2024-10-30 01:49:02
原创
169 人浏览过

  Why is the Placement of `wg.Add()` Crucial for Proper Synchronization in Go's `sync.WaitGroup`?

更正 wg.Add() 的 WaitGroup 同步位置

在 Go 中,sync.WaitGroup 类型提供 goroutine 之间的同步。它的主要目的是让主 goroutine 等待一组 goroutine 完成任务。然而,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(1) 调用放置在匿名函数,这是一个错误。这种错误的放置可能会导致 wg.Wait() 过早返回的情况,因为 wg.Add(1) 在同一 goroutine 中的 wg.Done() 之后执行。因此,v 将无法准确反映已完成任务的数量,其值可能会小于 100。

在更正的示例中:

<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( 1) call 现在被放置在匿名函数之外,确保主 goroutine 在调用 wg.Wait() 之前已经调用了所有 100 个 goroutine 并向 wg 注册了它们的完成任务。这个正确的放置保证了 wg.Wait() 将阻塞,直到所有 100 个 goroutine 完成其任务,从而获得准确的 v 值。

使用sync.WaitGroup 的一般规则:

为了确保使用sync.WaitGroup成功同步,请遵循以下准则:

  • 在启动新的goroutine之前,始终在主goroutine中调用wg.Add()。
  • 建议使用 defer 语句调用 wg.Done(),以确保即使在发生 Goroutine Panic 时也能执行。
  • 将sync.WaitGroup 传递给其他函数时(避免使用包级变量) ),向其传递一个指针以防止复制并确保所有更改均对原始的sync.WaitGroup进行。

以上是为什么 `wg.Add()` 的放置对于 Go 的 `sync.WaitGroup` 中的正确同步至关重要?的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责声明 Sitemap
PHP中文网:公益在线PHP培训,帮助PHP学习者快速成长!