在 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")
}