Golang WaitGroup使用指南

在Golang中使用WaitGroup时遇到了一些困惑:

  1. 为什么有时候WaitGroup的计数器会变成负数?
  2. 如何正确使用Add()和Done()方法来避免死锁?
  3. 在主goroutine中调用Wait()后,子goroutine还没执行完怎么办?
  4. WaitGroup和channel配合使用时有什么需要注意的?
  5. 有没有常见的WaitGroup使用错误示例可以参考?
    希望能得到一些实际代码示例和最佳实践建议。
2 回复

Golang中WaitGroup用于等待一组goroutine完成。使用Add()设置等待数,Done()减少计数,Wait()阻塞直到计数归零。注意避免Add()在goroutine内调用,防止竞态条件。示例:

var wg sync.WaitGroup
wg.Add(2)
go func() { defer wg.Done(); /*任务*/ }()
go func() { defer wg.Done(); /*任务*/ }()
wg.Wait()

更多关于Golang WaitGroup使用指南的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


Golang WaitGroup 使用指南

WaitGroup 是 Go 语言 sync 包中的一个重要同步原语,用于等待一组 goroutine 完成执行。

核心方法

var wg sync.WaitGroup

// 添加等待的 goroutine 数量
wg.Add(delta int)

// 标记一个 goroutine 完成
wg.Done()

// 阻塞等待所有 goroutine 完成
wg.Wait()

基本使用模式

package main

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

func worker(id int, wg *sync.WaitGroup) {
    defer wg.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 <= 3; i++ {
        wg.Add(1) // 每启动一个 goroutine 前增加计数
        go worker(i, &wg)
    }
    
    wg.Wait() // 等待所有 worker 完成
    fmt.Println("All workers completed")
}

重要注意事项

  1. Add 必须在 Wait 之前调用
  2. Done 调用次数必须与 Add 的总数匹配
  3. WaitGroup 应通过指针传递给 goroutine
  4. 不要复制 WaitGroup(会导致竞态条件)

常见错误模式

// 错误:在 goroutine 内部调用 Add
go func() {
    wg.Add(1)  // 竞态条件!
    defer wg.Done()
    // ...
}()

// 正确:在启动 goroutine 前调用 Add
wg.Add(1)
go func() {
    defer wg.Done()
    // ...
}()

实际应用场景

  • 并行处理批量任务
  • 等待多个后台服务启动完成
  • 并发执行多个网络请求

WaitGroup 是 Go 并发编程的基础工具,正确使用可以确保程序正确同步,避免 goroutine 泄漏。

回到顶部