ZBLOG

sync.WaitGroup

sync.WaitGroup 是 Go 语言标准库 sync 包中的一个并发原语,用于等待一组 Goroutine 完成执行。它通过计数器机制实现协程的同步,常用于主 Goroutine 阻塞等待所有子 Goroutine 完成任务后再继续执行。


核心方法

  1. Add(delta int)

    • 增加或减少 WaitGroup 的计数器值(通常为正数)。
    • 在启动新 Goroutine 前调用,表示需要等待的任务数。
    • delta 可以是负数(但需确保计数器不为负)。
  2. Done()

    • 将计数器减 1(等价于 Add(-1))。
    • 在 Goroutine 内部 defer 调用,确保任务完成后通知 WaitGroup。
  3. Wait()

    • 阻塞当前 Goroutine,直到计数器归零。
    • 通常由主 Goroutine 调用。

使用示例

package main

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

func worker(id int, wg *sync.WaitGroup) {
	defer wg.Done() // 确保任务完成后计数器减1
	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) // 每个任务开始前增加计数器
		go worker(i, &wg)
	}

	wg.Wait() // 阻塞直到所有任务完成
	fmt.Println("All workers completed")
}

关键注意事项

  1. 指针传递
    WaitGroup 必须通过指针传递给 Goroutine,否则会导致副本操作,引发死锁。

  2. 计数器的正确性

    • Add() 必须在 Wait() 之前调用(通常在启动 Goroutine 前)。
    • Done()次数必须与 Add()的总增量匹配,否则会 panic。
  3. 避免竞态条件
    不要在多个 Goroutine中并发调用 Add()(建议在主 Goroutine中集中管理)。

  4. 不可重用
    一个 WaitGroup在计数器归零后不能重复使用(除非重新初始化)。


典型应用场景

  • 批量异步任务等待:如并发处理一批文件下载、数据库查询等。
  • 服务优雅退出:等待所有后台 Goroutine清理资源后再关闭程序。
  • 测试多线程逻辑:确保所有测试用例的并发操作完成后再校验结果。

如果涉及更复杂的同步需求(如错误传递),可结合 channelerrgroup.Group(扩展库)使用。


内容由零声教学AI助手提供,问题来源于学员提问

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://golang.0voice.com/?id=23921

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?