sync.WaitGroup
是 Go 语言中用于等待一组 goroutine 完成的结构。它通常用于主 goroutine 等待其他 goroutine 完成后再继续执行。Add(1)
是 sync.WaitGroup
的一个重要方法,用于增加等待的 goroutine 数量。
Add(1)
的使用场景当你在主 goroutine 中启动一个新的 goroutine 时,你需要告诉 WaitGroup
有一个新的 goroutine 需要等待。这时你可以调用 Add(1)
来增加等待的计数器。
创建 WaitGroup
实例:首先你需要创建一个 sync.WaitGroup
的实例。
var wg sync.WaitGroup
调用 Add(1)
:在启动一个新的 goroutine 之前,调用 Add(1)
来增加等待的计数器。
wg.Add(1)
启动 goroutine:启动一个新的 goroutine,并在其中执行任务。
go func() {
defer wg.Done() // 确保在 goroutine 结束时调用 Done
// 执行任务
}()
调用 Wait()
:在主 goroutine 中调用 Wait()
来等待所有 goroutine 完成。
wg.Wait()
以下是一个完整的示例,展示了如何使用 sync.WaitGroup
和 Add(1)
来等待多个 goroutine 完成。
package main
import (
"fmt"
"sync"
"time"
)
func worker(id int, wg *sync.WaitGroup) {
defer wg.Done() // 确保在函数退出时调用 Done
fmt.Printf("Worker %d starting\n", id)
time.Sleep(time.Second) // 模拟耗时任务
fmt.Printf("Worker %d done\n", id)
}
func main() {
var wg sync.WaitGroup
for i := 1; i <= 5; i++ {
wg.Add(1) // 增加等待的 goroutine 数量
go worker(i, &wg)
}
wg.Wait() // 等待所有 goroutine 完成
fmt.Println("All workers done")
}
wg.Add(1)
:在每次启动一个新的 goroutine 之前调用,表示有一个新的 goroutine 需要等待。defer wg.Done()
:在 goroutine 结束时调用,表示该 goroutine 已经完成。Done()
会将等待的计数器减一。wg.Wait()
:主 goroutine 调用 Wait()
来阻塞,直到所有的 goroutine 都调用了 Done()
,即等待的计数器变为 0。Add(1)
必须在启动 goroutine 之前调用,否则可能会导致 Wait()
提前返回。Done()
必须在 goroutine 结束时调用,否则 Wait()
会一直阻塞。Add()
可以一次性增加多个计数器,例如 Add(5)
表示有 5 个 goroutine 需要等待。通过正确使用 sync.WaitGroup
和 Add(1)
,你可以有效地管理并发任务,并确保主 goroutine 在所有子 goroutine 完成后再继续执行。