
本文深入探讨了 sync.WaitGroup 在 Go 语言中的安全重用问题。通过示例代码和源码分析,阐明了 sync.WaitGroup 在 Wait() 调用后可以安全重用,并且可以并发地从多个 goroutine 中调用 Wait()。只要 Add 操作发生在 Wait 之前,就能保证程序的正确性。
sync.WaitGroup 是 Go 语言中用于等待一组 goroutine 完成的同步原语。它主要有三个方法:Add(delta int) 用于增加等待的 goroutine 数量,Done() 用于标记一个 goroutine 完成,Wait() 用于阻塞直到所有等待的 goroutine 都完成。
一个常见的问题是,在调用 Wait() 之后,是否可以安全地重用 sync.WaitGroup。答案是肯定的,可以安全重用。
sync.WaitGroup 的安全重用
Go 语言的设计允许 sync.WaitGroup 在 Wait() 调用后被安全地重用。这意味着你可以在一个循环中多次使用同一个 sync.WaitGroup,而无需每次都创建一个新的实例。
立即学习“go语言免费学习笔记(深入)”;
以下是一个示例,展示了如何在循环中重用 sync.WaitGroup:
package mainimport ( "fmt" "sync")func worker(who string, in <-chan int, wg *sync.WaitGroup) { for i := range in { fmt.Println(who, i) wg.Done() }}func main() { var wg sync.WaitGroup AIn := make(chan int, 1) BIn := make(chan int, 1) go worker("a:", AIn, &wg) go worker("b:", BIn, &wg) for i := 0; i < 4; i++ { wg.Add(2) AIn <- i BIn <- i wg.Wait() fmt.Println("main:", i) } close(AIn) close(BIn)}
在这个例子中,sync.WaitGroup 在循环的每次迭代中都被重用。每次迭代都会调用 wg.Add(2) 来增加等待的 goroutine 数量,然后启动两个 goroutine,并在它们完成时调用 wg.Done()。最后,wg.Wait() 用于等待这两个 goroutine 完成。
并发调用 Wait()
更进一步,sync.WaitGroup 甚至允许从多个 goroutine 中并发地调用 Wait()。这在某些复杂的并发场景中非常有用。
Add 操作必须在 Wait 之前
一个重要的前提条件是,Add 操作必须在 Wait 操作之前发生。如果 Wait 在 Add 之前被调用,可能会导致程序出现意想不到的行为,例如死锁。
sync.WaitGroup 的内部实现
为了更好地理解 sync.WaitGroup 的工作原理,我们可以简单了解一下它的内部实现。在 Go 语言的源码中,sync.WaitGroup 结构体包含一个互斥锁(Mutex)、两个 int32 类型的计数器(counter 和 waiters)以及一个信号量(sema)。
type WaitGroup struct { m sync.Mutex counter int32 waiters int32 sema *uint32}
m:互斥锁,用于保护 counter 和 waiters 的并发访问。counter:计数器,表示需要等待的 goroutine 数量。waiters:等待者的数量,即有多少个 goroutine 在等待 Wait() 返回。sema:信号量,用于在计数器变为零时唤醒等待的 goroutine。
注意事项
确保 Add 操作的参数为正数,表示要等待的 goroutine 数量。每次调用 Done() 都会减少计数器,当计数器变为零时,所有等待的 goroutine 都会被唤醒。避免在 Add 之后立即调用 Wait,这可能会导致程序死锁。
总结
sync.WaitGroup 是 Go 语言中一个强大而灵活的同步原语。它可以安全地重用,并且允许并发地调用 Wait()。只要确保 Add 操作发生在 Wait 之前,就可以放心地使用 sync.WaitGroup 来管理并发 goroutine 的执行。理解 sync.WaitGroup 的工作原理和注意事项,可以帮助你编写更健壮、更可靠的并发程序。
以上就是Golang 中 sync.WaitGroup 的安全重用指南的详细内容,更多请关注创想鸟其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1417496.html
微信扫一扫
支付宝扫一扫