在Golang中sync.WaitGroup的使用方法
在 Golang 中,sync.WaitGroup
是一个非常有用的同步机制,用于等待一组协程完成它们的工作。通过 wg.Add(n)
可以设置需要等待的协程数量,wg.Done()
用于告诉 WaitGroup
一个任务已经完成,而 wg.Wait()
会阻塞并等待直到所有的任务都完成。
使用方法详解
package main import ( "fmt" "sync" "time" ) func main() { var wg sync.WaitGroup // 使用 wg.Add(2) 表示我们有 2 个协程需要等待完成 wg.Add(2) // 启动第一个协程 go func() { defer wg.Done() // 当这个协程完成时调用 Done() time.Sleep(1 * time.Second) fmt.Println("Task 1 finished") }() // 启动第二个协程 go func() { defer wg.Done() // 当这个协程完成时调用 Done() time.Sleep(2 * time.Second) fmt.Println("Task 2 finished") }() // 在主协程中等待所有的任务完成 wg.Wait() fmt.Println("All tasks finished") }
代码运行解释:
- 创建
sync.WaitGroup
对象
- 通过
var wg sync.WaitGroup
创建一个等待组对象。
- 设置需要等待的协程数量
wg.Add(2)
表示我们有 2 个需要等待的任务(协程)。每次Add(n)
后,你需要确保Done()
的调用次数和Add()
相匹配,否则会导致程序永远不会停止等待或者 panic。
- 启动协程
- 使用
go
关键字启动两个协程,并在协程中处理任务。
- 调用
wg.Done()
- 每次协程完成任务后使用
wg.Done()
标记一个任务已完成。这会减少WaitGroup
的计数。
- 阻塞直到完成
- 在主协程中调用
wg.Wait()
。这会阻塞主协程直到计数器归零(即所有任务完成)。
注意事项
- Add 和 Done 的配对
确保Add(n)
和Done()
调用次数是严格配对的。如果协程不正确调用Done()
,进程就会一直被阻塞在Wait()
。 - Add 要在启动协程之前调用
- 如果
wg.Add(n)
写在go
关键字的调用之后,你可能会出现竞态条件的问题,因为协程可能已经调用了Done()
导致计数器减到了非预期的值。
- defer 的使用
- 在协程内部使用
defer wg.Done()
是一个常见的写法,可以确保即使协程内部出现异常,Done()
也会被调用。
实践意义
sync.WaitGroup
可以帮助我们管理多协程并发,这在处理并行任务时非常有用,例如:
- 并发下载文件或处理数据块。
- 并行计算的完成后,再进行下一步的操作。
关注公众号:程序新视界,一个让你软实力、硬技术同步提升的平台
除非注明,否则均为程序新视界原创文章,转载必须以链接形式标明本文链接
本文链接:http://www.choupangxia.com/2025/08/02/golang-sync-waitgroup/