登录
首页 >  Golang >  Go教程

GolangWaitGroup使用与并发同步技巧

时间:2025-12-09 09:30:27 102浏览 收藏

推广推荐
免费电影APP ➜
支持 PC / 移动端,安全直达

最近发现不少小伙伴都对Golang很感兴趣,所以今天继续给大家介绍Golang相关的知识,本文《Golang WaitGroup使用技巧与并发同步方法》主要内容涉及到等等知识点,希望能帮到你!当然如果阅读本文时存在不同想法,可以在评论中表达,但是请勿使用过激的措辞~

WaitGroup 是协程生命周期协调器,非同步锁;须主 goroutine 初始化并传指针,Add 在启动前、Done 用 defer、Wait 在启动后;需配合 Mutex 或 channel 防数据竞争,避免死锁。

如何在Golang中高效使用WaitGroup_Golang WaitGroup并发同步方法

在 Go 中高效使用 sync.WaitGroup,核心是理解它只负责“计数等待”,不提供锁或数据保护——它不是万能同步工具,而是协程生命周期的轻量协调器。

WaitGroup 的正确初始化与作用域

WaitGroup 必须在启动 goroutine 前初始化,且不能复制(它是含 mutex 的结构体)。推荐在函数顶部声明,避免作为参数传递或跨 goroutine 复制:

  • ✅ 正确:在主 goroutine 中定义 var wg sync.WaitGroup,再用 wg.Add(n)
  • ❌ 错误:把 wg 作为值传给 goroutine(会复制,子 goroutine 调用 Done() 不影响原 wg)
  • ⚠️ 注意:若需在多个函数间协作,应传指针 *sync.WaitGroup,但更推荐逻辑收拢、由调用方统一管理

Add、Done、Wait 的调用顺序不能乱

Add() 必须在 go 启动前调用;Done() 应在 goroutine 结束前调用(通常用 defer wg.Done() 最安全);Wait() 放在所有 goroutine 启动之后、需要等待结果之前:

  • ✅ 推荐写法:wg.Add(1); go func() { defer wg.Done(); /* work */ }()
  • ❌ 危险写法:go func() { wg.Add(1); /* ... */ wg.Done() }() —— Add 和 Done 都在子 goroutine 中,主 goroutine 可能提前 Wait 返回
  • ⚠️ 特别注意:Add 的参数可为负数,但仅用于调试或特殊场景;生产代码中应确保 Add 总在 Done 前,且总和匹配

WaitGroup 不替代互斥锁,数据竞争仍需 sync.Mutex 或 channel

WaitGroup 只告诉“哪些 goroutine 结束了”,不保证它们访问共享变量的安全性。例如并发累加计数器:

  • ❌ 错误:只用 wg 等待,却直接读写 sum++ → 数据竞争
  • ✅ 正确:配合 sync.Mutex 保护临界区,或改用 channel 汇总结果(如每个 goroutine 发送结果到 channel,主 goroutine range 收集)
  • ? 小技巧:对简单聚合(如统计数量),可用原子操作 atomic.AddInt64(&counter, 1) 替代锁+wg,更轻量

避免死锁:超时等待与 panic 安全

Wait() 是阻塞调用,若 goroutine 异常退出未调用 Done(),主 goroutine 将永久挂起。应对方法:

  • ✅ 总用 defer wg.Done(),确保无论是否 panic 都执行
  • ✅ 对关键流程加 context 超时:select { case
  • ⚠️ 不要手动调用 wg.Add(-1) 补救遗漏的 Done —— 易引发 panic 或逻辑错乱

基本上就这些。WaitGroup 本身很简单,真正决定效率的是你如何组织 goroutine 生命周期、隔离共享状态、以及是否混淆了“等待完成”和“保护数据”的职责。

今天关于《GolangWaitGroup使用与并发同步技巧》的内容介绍就到此结束,如果有什么疑问或者建议,可以在golang学习网公众号下多多回复交流;文中若有不正之处,也希望回复留言以告知!

相关阅读
更多>
最新阅读
更多>
课程推荐
更多>