Go 语言中如何使用 sync.WaitGroup 等待 goroutine 结束?

推荐答案

在 Go 语言中,sync.WaitGroup 用于等待一组 goroutine 完成。以下是使用 sync.WaitGroup 的基本步骤:

  1. 创建一个 sync.WaitGroup 实例。
  2. 在启动每个 goroutine 之前,调用 WaitGroup.Add(1) 来增加计数器。
  3. 在每个 goroutine 完成时,调用 WaitGroup.Done() 来减少计数器。
  4. 在主 goroutine 中调用 WaitGroup.Wait() 来阻塞,直到所有 goroutine 完成。

示例代码如下:

-- -------------------- ---- -------
------- ----

------ -
    -----
    ------
    ------
-

---- --------- ---- -- ---------------- -
    ----- --------- -- ---------- ----
    ------------------ -- ------------ ---
    ----------------------- -- ----
    ------------------ -- -------- ---
-

---- ------ -
    --- -- --------------

    --- - -- -- - -- -- --- -
        --------- -- -----
        -- --------- ----
    -

    --------- -- ---- --------- --
    ---------------- ------- ------
-

本题详细解读

1. sync.WaitGroup 的作用

sync.WaitGroup 是 Go 语言中用于同步多个 goroutine 的工具。它通过一个计数器来跟踪正在执行的 goroutine 数量。主 goroutine 可以通过 Wait() 方法阻塞,直到所有其他 goroutine 完成。

2. WaitGroup 的主要方法

  • Add(delta int):增加或减少 WaitGroup 的计数器。通常在每个 goroutine 启动前调用 Add(1)
  • Done():减少 WaitGroup 的计数器。通常在 goroutine 完成时调用,等同于 Add(-1)
  • Wait():阻塞主 goroutine,直到 WaitGroup 的计数器归零。

3. 使用 defer 调用 Done()

在示例代码中,defer wg.Done() 确保了即使 goroutine 提前返回或发生 panic,Done() 也会被调用。这是一种良好的编程习惯,可以避免资源泄漏或死锁。

4. 传递 WaitGroup 的指针

在示例中,WaitGroup 是通过指针传递给 goroutine 的。这是因为 WaitGroup 是一个结构体,如果传递值拷贝,每个 goroutine 将操作不同的 WaitGroup 实例,导致无法正确同步。

5. 适用场景

sync.WaitGroup 适用于需要等待一组 goroutine 完成的场景,例如并发任务处理、批量数据处理等。它提供了一种简单而有效的方式来管理并发任务的同步。

6. 注意事项

  • 确保 Add()Done() 的调用次数匹配,否则可能导致死锁或 panic。
  • 不要在 goroutine 内部调用 Add(),因为这可能导致竞态条件。
  • WaitGroup 不能重复使用,一旦计数器归零,再次使用需要重新初始化。
纠错
反馈