如何使用Golang WaitGroup和mutex实现并发控制_组合同步工具管理任务
发布时间 - 2025-12-29 00:00:00 点击率:次Go 中 sync.WaitGroup 与 sync.Mutex 组合可协调 goroutine 生命周期与共享资源访问:WaitGroup 通过 Add/Wait/Done 控制任务启停,Mutex 通过锁机制防止数据竞争,二者分工明确、配合自然。
使用 Go 的 sync.WaitGroup 和 sync.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()后,再安全读取success和fail
注意:不要把 mu.Lock() 放在 WaitGroup 的 Add/Wait 调用路径上——它们无需同步,加锁只会拖慢调度。
替代方案与注意事项
对于简单计数,可考虑 sync/atomic(如 atomic.AddInt64),它比 Mutex 更轻量且无锁;但仅适用于基础类型和有限操作。若需复杂结构(如向切片追加、修改 map),仍需 Mutex。
另外,WaitGroup 无法取消或超时;如有此需求,应结合 context.Context 控制 goroutine 生命周期,WaitGroup 仅用于收尾等待。
# go
# golang
# 工具
# ai
# 无锁
# 有锁
# int
# 线程
# var
# 切片
# map
# 并发
# 多个
# 加锁
# 死锁
# 它不
# 放在
# 最多
# 如有
# 不要在
# 长时间
# 适用于
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
制作公司内部网站有哪些,内网如何建网站?
开心动漫网站制作软件下载,十分开心动画为何停播?
如何实现建站之星域名转发设置?
jquery插件bootstrapValidator表单验证详解
Laravel如何使用Passport实现OAuth2?(完整配置步骤)
香港代理服务器配置指南:高匿IP选择、跨境加速与SEO优化技巧
北京专业网站制作设计师招聘,北京白云观官方网站?
宙斯浏览器文件分类查看教程 快速筛选视频文档与图片方法
js代码实现下拉菜单【推荐】
音响网站制作视频教程,隆霸音响官方网站?
jQuery 常见小例汇总
Laravel怎么使用Markdown渲染文档_Laravel将Markdown内容转HTML页面展示【实战】
晋江文学城电脑版官网 晋江文学城网页版直接进入
Laravel如何发送邮件和通知_Laravel邮件与通知系统发送步骤
Laravel Eloquent关联是什么_Laravel模型一对一与一对多关系精讲
HTML透明颜色代码怎么让下拉菜单透明_下拉菜单透明背景指南【技巧】
海南网站制作公司有哪些,海口网是哪家的?
佛山企业网站制作公司有哪些,沟通100网上服务官网?
Laravel如何创建自定义中间件?(Middleware代码示例)
如何用PHP工具快速搭建高效网站?
Laravel怎么实现模型属性的自动加密
如何在阿里云香港服务器快速搭建网站?
Laravel怎么实现前端Toast弹窗提示_Laravel Session闪存数据Flash传递给前端【方法】
如何在IIS中新建站点并解决端口绑定冲突?
php后缀怎么变mp4格式错误_修改扩展名提示格式不对怎么办【技巧】
Python函数文档自动校验_规范解析【教程】
bootstrap日历插件datetimepicker使用方法
JavaScript常见的五种数组去重的方式
html5的keygen标签为什么废弃_替代方案说明【解答】
HTML5空格和nbsp有啥关系_nbsp的作用及使用场景【说明】
网页制作模板网站推荐,网页设计海报之类的素材哪里好?
javascript中的try catch异常捕获机制用法分析
网站图片在线制作软件,怎么在图片上做链接?
Laravel如何实现一对一模型关联?(Eloquent示例)
Laravel Eloquent模型如何创建_Laravel ORM基础之Model创建与使用教程
如何注册花生壳免费域名并搭建个人网站?
php打包exe后无法访问网络共享_共享权限设置方法【教程】
实例解析angularjs的filter过滤器
如何为不同团队 ID 动态生成多个独立按钮
图片制作网站免费软件,有没有免费的网站或软件可以将图片批量转为A4大小的pdf?
如何在搬瓦工VPS快速搭建网站?
Laravel如何实现密码重置功能_Laravel密码找回与重置流程
惠州网站建设制作推广,惠州市华视达文化传媒有限公司怎么样?
Laravel怎么为数据库表字段添加索引以优化查询
微信小程序 canvas开发实例及注意事项
Python自然语言搜索引擎项目教程_倒排索引查询优化案例
Laravel安装步骤详细教程_Laravel环境搭建指南
INTERNET浏览器怎样恢复关闭标签页_INTERNET浏览器标签恢复快捷键与方法【指南】
Chrome浏览器标签页分组怎么用_谷歌浏览器整理标签页技巧【效率】
Laravel怎么进行数据库回滚_Laravel Migration数据库版本控制与回滚操作

