Go 示例: WaitGroup

要等待多个 goroutine 完成,我们可以使用 wait group

package main
import (
    "fmt"
    "sync"
    "time"
)

这是我们将在每个 goroutine 中运行的函数。

func worker(id int) {
    fmt.Printf("Worker %d starting\n", id)

休眠以模拟一项耗时的任务。

    time.Sleep(time.Second)
    fmt.Printf("Worker %d done\n", id)
}
func main() {

此 WaitGroup 用于等待此处启动的所有 goroutine 完成。注意:如果将 WaitGroup 显式传递给函数,则应 通过指针 传递。

    var wg sync.WaitGroup

启动多个 goroutine 并为每个 goroutine 增加 WaitGroup 计数器。

    for i := 1; i <= 5; i++ {
        wg.Add(1)

将 worker 调用包装在一个闭包中,确保告诉 WaitGroup 此 worker 已完成。这样,worker 本身无需了解其执行中涉及的并发原语。

        go func() {
            defer wg.Done()
            worker(i)
        }()
    }

阻塞,直到 WaitGroup 计数器恢复为 0;所有 worker 都已通知完成。

    wg.Wait()

请注意,这种方法没有直接的方法来传播来自 worker 的错误。对于更高级的用例,请考虑使用 errgroup 包

}
$ go run waitgroups.go
Worker 5 starting
Worker 3 starting
Worker 4 starting
Worker 1 starting
Worker 2 starting
Worker 4 done
Worker 1 done
Worker 2 done
Worker 5 done
Worker 3 done

worker 启动和完成的顺序在每次调用时可能不同。

下一个示例:速率限制