Go - 使用 sync.WaitGroup 来实现并发操作
2023-03-14 22:31:49 时间
文章目录:
- 前言
- sync.WaitGroup 正确使用
- sync.WaitGroup 闭坑指南
- 01
- 02
- 03
- 小结
- 推荐阅读
前言
如果你有一个任务可以分解成多个子任务进行处理,同时每个子任务没有先后执行顺序的限制,等到全部子任务执行完毕后,再进行下一步处理。这时每个子任务的执行可以并发处理,这种情景下适合使用 sync.WaitGroup
。
虽然 sync.WaitGroup
使用起来比较简单,但是一不留神很有可能踩到坑里。
sync.WaitGroup 正确使用
比如,有一个任务需要执行 3 个子任务,那么可以这样写:
func main() {
var wg sync.WaitGroup
wg.Add(3)
go handlerTask1(&wg)
go handlerTask2(&wg)
go handlerTask3(&wg)
wg.Wait()
fmt.Println("全部任务执行完毕.")
}
func handlerTask1(wg *sync.WaitGroup) {
defer wg.Done()
fmt.Println("执行任务 1")
}
func handlerTask2(wg *sync.WaitGroup) {
defer wg.Done()
fmt.Println("执行任务 2")
}
func handlerTask3(wg *sync.WaitGroup) {
defer wg.Done()
fmt.Println("执行任务 3")
}
执行输出:
执行任务 3
执行任务 1
执行任务 2
全部任务执行完毕.
sync.WaitGroup 闭坑指南
01
// 正确
go handlerTask1(&wg)
// 错误
go handlerTask1(wg)
执行子任务时,使用的 sync.WaitGroup
一定要是 wg
的引用类型!
02
注意不要将 wg.Add()
放在 go handlerTask1(&wg)
中!
例如:
// 错误
var wg sync.WaitGroup
go handlerTask1(&wg)
wg.Wait()
...
func handlerTask1(wg *sync.WaitGroup) {
wg.Add(1)
defer wg.Done()
fmt.Println("执行任务 1")
}
注意 wg.Add()
一定要在 wg.Wait()
执行前执行!
03
注意 wg.Add()
和 wg.Done()
的计数器保持一致!其实 wg.Done()
就是执行的 wg.Add(-1)
。
小结
sync.WaitGroup
使用起来比较简单,一定要注意不要踩到坑里。
其实 sync.WaitGroup
使用场景比较局限,仅适用于等待全部子任务执行完毕后,再进行下一步处理,如果需求是当第一个子任务执行失败时,通知其他子任务停止运行,这时 sync.WaitGroup
是无法满足的,需要使用到通知机制(channel
)。
以上,希望对你能够有所帮助。
相关文章
- 在 Go 里用 CGO?这 7 个问题你要关注!
- 9款优秀的去中心化通讯软件 Matrix 的客户端
- 求职数据分析,项目经验该怎么写
- 在OKR中,我看到了数据驱动业务的未来
- 火山引擎云原生大数据在金融行业的实践
- OpenHarmony富设备移植指南(二)—从postmarketOS获取移植资源
- 《数据成熟度指数》报告:64%的企业领袖认为大多数员工“不懂数据”
- OpenHarmony 小型系统兼容性测试指南
- 肯睿中国(Cloudera):2023年企业数字战略三大趋势预测
- 适用于 Linux 的十大命令行游戏
- GNOME 截图工具的新旧截图方式
- System76 即将推出的 COSMIC 桌面正在酝酿大变化
- 2GB 内存 8GB 存储即可流畅运行,Windows 11 极致精简版系统 Tiny11 发布
- 迎接 ecode:一个即将推出的具有全新图形用户界面框架的现代、轻量级代码编辑器
- loongarch架构介绍(三)—地址翻译
- Go 语言怎么解决编译器错误“err is shadowed during return”?
- 敏捷:可能被开发人员遗忘的部分
- Denodo预测2023年数据管理和分析的未来
- 利用数据推动可持续发展
- 在 Vue3 中实现 React 原生 Hooks(useState、useEffect),深入理解 React Hooks 的