登录
首页 >  Golang >  Go教程

GolangWaitGroup与Mutex并发控制详解

时间:2026-01-02 16:53:42 257浏览 收藏

哈喽!今天心血来潮给大家带来了《Golang WaitGroup与Mutex并发控制实战》,想必大家应该对Golang都不陌生吧,那么阅读本文就都不会很困难,以下内容主要涉及到,若是你正在学习Golang,千万别错过这篇文章~希望能帮助到你!

Go 中 sync.WaitGroup 与 sync.Mutex 组合可协调 goroutine 生命周期与共享资源访问:WaitGroup 通过 Add/Wait/Done 控制任务启停,Mutex 通过锁机制防止数据竞争,二者分工明确、配合自然。

如何使用Golang WaitGroup和mutex实现并发控制_组合同步工具管理任务

使用 Go 的 sync.WaitGroupsync.Mutex 组合,能有效协调多个 goroutine 的生命周期与共享资源访问——WaitGroup 负责“等任务完成”,Mutex 负责“防数据竞争”,二者分工明确,配合自然。

WaitGroup 控制任务启停节奏

WaitGroup 适合管理一组并发任务的启动与等待。它不关心任务内部逻辑,只跟踪“谁还没结束”。核心是三个方法:Add()(预设任务数)、Done()(标记完成)、Wait()(阻塞直到全部完成)。

  • 必须在启动 goroutine 前调用 Add(1),不能在 goroutine 内部 Add —— 否则可能 Wait 提前返回
  • Done() 应该和 Add(1) 严格配对;推荐用 defer wg.Done() 避免遗漏
  • WaitGroup 本身不是线程安全的:Add 和 Wait 不能并发调用;Add 必须在所有 goroutine 启动前完成

Mutex 保护共享状态不被并发篡改

当多个 goroutine 共同更新一个变量(如计数器、切片、map)时,必须用 Mutex 加锁。它不控制执行顺序,只确保同一时刻最多一个 goroutine 进入临界区。

  • 锁的粒度要合适:太粗(如整个函数加锁)会降低并发性;太细(每行都 lock/unlock)易出错且无必要
  • 优先使用 mu.Lock()/mu.Unlock() 配对,或更稳妥地用 defer mu.Unlock()
  • 避免死锁:不要在持有锁时调用可能再次获取同一把锁的函数;不要在锁内长时间阻塞(如网络请求、time.Sleep)

组合使用:一边等结果,一边安全更新状态

典型场景是并发处理一批数据,并汇总结果(比如统计成功/失败数量、收集返回值)。WaitGroup 确保主协程不提前退出,Mutex 保证汇总操作线程安全。

示例逻辑:

  • 定义全局计数器和互斥锁:var success, fail int; var mu sync.Mutex
  • 启动 N 个 goroutine,每个执行任务后根据结果调用 mu.Lock(); success++; mu.Unlock() 或类似操作
  • 主 goroutine 调用 wg.Wait() 后,再安全读取 successfail

注意:不要把 mu.Lock() 放在 WaitGroup 的 Add/Wait 调用路径上——它们无需同步,加锁只会拖慢调度。

替代方案与注意事项

对于简单计数,可考虑 sync/atomic(如 atomic.AddInt64),它比 Mutex 更轻量且无锁;但仅适用于基础类型和有限操作。若需复杂结构(如向切片追加、修改 map),仍需 Mutex。

另外,WaitGroup 无法取消或超时;如有此需求,应结合 context.Context 控制 goroutine 生命周期,WaitGroup 仅用于收尾等待。

本篇关于《GolangWaitGroup与Mutex并发控制详解》的介绍就到此结束啦,但是学无止境,想要了解学习更多关于Golang的相关知识,请关注golang学习网公众号!

前往漫画官网入口并下载 ➜
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>