在 Go 中,sync 包下的 WaitGroup 能有助于我们控制协程之间的同步。当需要等待一组协程都执行完各自任务后,才能继续后续逻辑。这种场景,就非常适合使用它。
WaitGroup 提供三个 API。
Add(delta int) 函数提供了 WaitGroup 的任务计数,delta 的值可以为正也可以为负,通常在添加任务时使用。
Done() 函数其实就是 Add(-1),在任务完成时调用。
Wait() 函数用于阻塞等待 WaitGroup 的任务们均完成,即阻塞等待至任务数为 0。
方式一:
package main import ( "fmt" "sync" ) func worker(msg string, wg *sync.WaitGroup) { wg.Add(1) defer wg.Done() fmt.Printf("worker do %s\n", msg) } func main() { var wg sync.WaitGroup go worker("task 1", &wg) go worker("task 2", &wg) go worker("task 3", &wg) go worker("task 4", &wg) go worker("task 5", &wg) fmt.Println("waiting") wg.Wait() fmt.Println("main exit") }
方式二:
package main import ( "fmt" "sync" ) func worker(msg string) { fmt.Printf("worker do %s\n", msg) } func main() { var wg sync.WaitGroup for i := 0; i < 5; i++ { wg.Add(1) go func(i int) { defer wg.Done() worker(fmt.Sprintf("task %d", i+1)) }(i) } fmt.Println("waiting") wg.Wait() fmt.Println("main exit") }