插件窝 干货文章 Go语言sync.WaitGroup的Add(1)究竟该如何使用?

Go语言sync.WaitGroup的Add(1)究竟该如何使用?

goroutine 调用 等待 WaitGroup 911    来源:    2025-03-15

sync.WaitGroup 是 Go 语言中用于等待一组 goroutine 完成的结构。它通常用于主 goroutine 等待其他 goroutine 完成后再继续执行。Add(1)sync.WaitGroup 的一个重要方法,用于增加等待的 goroutine 数量。

Add(1) 的使用场景

当你在主 goroutine 中启动一个新的 goroutine 时,你需要告诉 WaitGroup 有一个新的 goroutine 需要等待。这时你可以调用 Add(1) 来增加等待的计数器。

使用步骤

  1. 创建 WaitGroup 实例:首先你需要创建一个 sync.WaitGroup 的实例。

    var wg sync.WaitGroup
    
  2. 调用 Add(1):在启动一个新的 goroutine 之前,调用 Add(1) 来增加等待的计数器。

    wg.Add(1)
    
  3. 启动 goroutine:启动一个新的 goroutine,并在其中执行任务。

    go func() {
       defer wg.Done() // 确保在 goroutine 结束时调用 Done
       // 执行任务
    }()
    
  4. 调用 Wait():在主 goroutine 中调用 Wait() 来等待所有 goroutine 完成。

    wg.Wait()
    

示例代码

以下是一个完整的示例,展示了如何使用 sync.WaitGroupAdd(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.WaitGroupAdd(1),你可以有效地管理并发任务,并确保主 goroutine 在所有子 goroutine 完成后再继续执行。