返回文章列表

文章

go中sync.WaitGroup的用法

sync.WaitGroup 是等待多个并发任务完成的简洁方式

目录
  1. 在 Go 中,sync.WaitGroup 是一个非常常用的同步原语,用于等待一组 goroutine 执行完成。
  2. 🧩 基本使用场景
  3. 当你有多个 goroutine 并发执行任务,并希望主线程等待所有 goroutine 完成后再继续往下执行时,就用 WaitGroup。
  4. ✅ 使用方式
  5. 📌 方法说明
  6. ⚠️ 使用注意事项
  7. 🧠 示例:并发处理任务列表
  8. ✅ 总结
  9. 📎 参考文章

在 Go 中,sync.WaitGroup 是一个非常常用的同步原语,用于等待一组 goroutine 执行完成。#

🧩 基本使用场景#

当你有多个 goroutine 并发执行任务,并希望主线程等待所有 goroutine 完成后再继续往下执行时,就用 WaitGroup#

✅ 使用方式#

import (
    "fmt"
    "sync"
    "time"
)

func main() {
    var wg sync.WaitGroup  // 创建 WaitGroup

    for i := 1; i <= 3; i++ {
        wg.Add(1) // 启动一个 goroutine 前加 1

        go func(id int) {
            defer wg.Done() // goroutine 结束时调用 Done
            fmt.Printf("Goroutine %d starting\n", id)
            time.Sleep(time.Second)
            fmt.Printf("Goroutine %d done\n", id)
        }(i)
    }

    wg.Wait() // 阻塞等待,直到计数归零
    fmt.Println("All goroutines finished")
}


📌 方法说明#

方法作用
`Add(n int)`设置/增加等待的 goroutine 数量。通常在启动前调用。
`Done()`当前 goroutine 结束时调用,表示完成了一个任务,相当于 `Add(-1)`。
`Wait()`阻塞当前调用者,直到计数器归零(即所有任务完成)。

⚠️ 使用注意事项#

  1. Add 必须在 goroutine 启动之前调用 否则可能在 goroutine 启动前 Wait() 已执行,造成提前结束。
  2. 不要在多个 goroutine 中同时调用 Add Add() 通常放在主 goroutine 或统一的地方管理,避免竞态。
  3. 避免 WaitGroup 复用 Wait() 返回后,不要重用已用过的 WaitGroup,否则可能导致数据竞态或 panic。
  4. 不要忘记 Done() 每个 Add(1) 必须有对应的 Done(),否则 Wait() 永远阻塞。

🧠 示例:并发处理任务列表#

tasks := []int{1, 2, 3, 4, 5}
var wg sync.WaitGroup

for _, t := range tasks {
    wg.Add(1)
    go func(task int) {
        defer wg.Done()
        fmt.Println("Processing task:", task)
        time.Sleep(500 * time.Millisecond)
    }(t)
}

wg.Wait()
fmt.Println("All tasks processed")

✅ 总结#

  • sync.WaitGroup 是等待多个并发任务完成的简洁方式;
  • 每个任务调用 Add(1),结束时 Done()
  • Wait() 会阻塞,直到所有 goroutine 都完成;
  • 使用简单但一定要注意正确调用 AddDone 的时机。

📎 参考文章#