Go语言中`WaitGroup`的介绍和使用示例
关于Go语言中WaitGroup的介绍和使用示例,咱们用轻松易懂的方式分步拆解,并附上实用代码片段。以下内容结构清晰,适合新手到进阶开发者阅读👇
一、什么是WaitGroup?
WaitGroup是Go语言sync包提供的并发控制工具,核心作用是让主协程(goroutine)等待一组子协程全部完成任务后再继续执行。类似其他语言中的“线程栅栏”。
适用场景举例:
- 批量处理任务(如并发下载多个文件)
- 数据分片计算后汇总结果
- 确保所有协程就绪后再触发主逻辑
二、核心方法:3个关键操作
WaitGroup仅包含3个方法,轻松上手:
-
Add(int)
设置需要等待的协程数量。例如,启动5个任务时调用wg.Add(5)。 -
Done()
每个协程完成任务后调用,相当于计数器减1。通常用defer wg.Done()确保执行。 -
Wait()
主协程调用此方法会阻塞,直到所有子协程完成(计数器归零)。
三、使用示例:分步骤指南
示例1:基础用法(模拟并发任务)
package main
import (
"fmt"
"sync"
"time"
)
func main() {
var wg sync.WaitGroup
taskCount := 3
wg.Add(taskCount)
for i := 0; i < taskCount; i++ {
go func(id int) {
defer wg.Done() // 确保任务完成时调用
time.Sleep(time.Duration(id) * time.Second)
fmt.Printf("任务%d完成!\n", id)
}(i)
}
fmt.Println("主协程等待中...")
wg.Wait()
fmt.Println("所有任务完成!")
}
输出结果:
主协程等待中...
任务0完成!
任务1完成!
任务2完成!
所有任务完成!
解析:主协程通过wg.Wait()等待,直到3个子协程均调用Done()。
示例2:实战场景(并发检查就绪状态)
参考中的“赛跑”案例,模拟所有运动员就位后触发发令:
func main() {
var wait sync.WaitGroup
runnerCount := 5
wait.Add(runnerCount)
for i := 0; i < runnerCount; i++ {
go func(id int) {
defer wait.Done()
fmt.Printf("运动员%d已就位\n", id)
}(i)
}
fmt.Println("等待所有运动员准备...")
wait.Wait()
fmt.Println("发令枪响!比赛开始!")
}
四、注意事项(避坑指南)
-
计数器匹配:
Add(n)的参数必须与后续Done()调用次数一致,否则可能引发panic。- 建议在启动协程前调用
Add(),避免并发操作导致计数错误。
-
避免重用问题:
一组WaitGroup未完全结束前(如还在Wait()中),不要复用同一实例。 -
延迟调用
Done():
使用defer wg.Done()确保即使协程异常退出也能减少计数器。
五、总结
WaitGroup是Go语言并发编程中的“协调员”,通过简洁的API实现多协程同步。使用时牢记计数器匹配原则,结合defer确保健壮性,即可轻松驾驭并发任务场景~
- 《Go 程序设计语言》(Go 语言圣经,机械工业出版社) —— Go 官方团队出品,公认入门第一书
- 《Go 语言实战》(异步图书,人民邮电出版社) —— 实战导向,面试前巩固工程手感
- 《Go 语言编程之旅:一起用 Go 做项目》(博文视点,电子工业出版社) —— 项目驱动入门,从零写出完整应用
- Keychron K1Max 矮轴机械键盘(Mac/Win 双系统,QMK/VIA 开源改键) —— 轻薄矮轴 + 开源固件,程序员桌面常客
- 罗技 MX Master 3S 无线鼠标(Flow 跨屏,静音电磁滚轮) —— 人体工学设计,写代码一整天手不酸
以上链接含京东联盟推广代码;通过链接购买本站可能获得少量佣金,不影响你的购买价格。
每周更新 Go + AI 应用开发实战:AI 面试官完整项目、MCP、Agent 工程化,完整源码随文章首发。
微信扫码,或搜索「GO语言入门之路」关注,第一时间获取系列更新与源码,不再错过任何一篇。