全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

如何使用Golang通过WaitGroup同步协程_Golang协程同步机制讲解

sync.WaitGroup 是 Go 中用于等待一组 goroutine 完成的轻量同步工具,核心为 Add、Done、Wait 三步,需注意计数匹配、避免复制和误调用。

Go 语言中,sync.WaitGroup 是最常用、最轻量的协程(goroutine)同步工具之一,用于等待一组协程执行完毕。它不关心协程内部逻辑,只负责“计数”和“阻塞等待”,适合主协程等待多个子协程完成后再继续执行的场景。

WaitGroup 的核心三步用法

WaitGroup 的使用遵循固定模式:声明 → 增加计数 → 启动协程 → 等待完成。漏掉任意一步都可能导致 panic 或死锁。

  • 声明 WaitGroup 变量:通常在主 goroutine 中定义,如 var wg sync.WaitGroup
  • 调用 wg.Add(n):在启动协程前,把要等待的协程数量加进去(n > 0)。注意不能在协程里调用 Add,否则可能因竞态导致计数错误
  • 协程内调用 wg.Done():每个协程结束前必须调用一次,等价于 wg.Add(-1)。推荐用 defer wg.Done() 确保执行
  • 主协程调用 wg.Wait():会阻塞直到内部计数归零。该调用应放在所有 go 语句之后,且只能被调用一次

常见误用与避坑指南

WaitGroup 表面简单,但几个典型错误会让程序崩溃或卡死:

  • Add 在 goroutine 内调用:因为 Add 和 Wait 之间没有同步保障,可能 Wait 先执行,计数仍为 0,直接返回,后续 Done 导致 panic(计数负值)
  • Done 调用次数不匹配:比如某个分支没执行 defer Done,或重复调用 Done,都会破坏计数平衡
  • Wait 被多次调用:Wait 不是重入安全的,第二次调用会 panic
  • WaitGroup 被复制传递:WaitGroup 不可拷贝(含结构体字段赋值、函数传值、切片 append 等),应始终传指针:func worker(wg *sync.WaitGroup, job int)

一个实用示例:并发请求并汇总结果

模拟向多个 URL 发起 HTTP 请求,并等待全部完成:

func fetchAll(urls []string) {
    var wg sync.WaitGroup
    results := make(chan string, len(urls))
for _, url := range urls {
    wg.Add(1)
    go func(u string) {
        defer wg.Done()
        resp, err := http.Get(u)
        if err != nil {
            results <- "error: " + err.Error()
            return
        }
        results <- fmt.Sprintf("success: %s", resp.Status)
    }(url) // 注意:需传参避免闭包引用同一变量
}

go func() {
    wg.Wait()
    close(results)
}()

for res := range results {
    fmt.Println(res)
}

}

这个例子体现了 WaitGroup 和 channel 的配合:WaitGroup 确保所有请求发起并结束,channel 收集结果,避免额外锁或共享变量。

WaitGroup vs 其他同步机制

不是所有并发等待都要用 WaitGroup:

  • 需要精确控制顺序或条件等待:用 sync.Mutex + sync.Condsync.Once
  • 等待带超时或取消:用 context.Context 配合 channel select,WaitGroup 本身不支持超时
  • 只需通知一次事件sync.Once 更合适;若需多次通知,考虑 chan struct{}sync.Cond
  • 等待多个不同信号且有数据传递:优先选 channel,语义更清晰、组合性更强

WaitGroup 的定位很明确:**仅做“数量同步”,不做“通信”或“协调”。用对了,简洁高效;用错了,调试困难。

基本上就这些。WaitGroup 不复杂但容易忽略细节,掌握 Add/Wait/Done 的时机和生命周期,就能稳稳控住并发节奏。


# go  # golang  # app  # 工具  # ai  # 并发请求  # 同步机制  # select  # 结构体  # int  # 指针  # Struct  # var  # 切片  # append  # 并发  # channel  # 事件  # http  # 多个  # 死锁  # 三步  # 几个  # 放在  # 就能  # 只需  # 能在  # 错了  # 要用 


相关文章: 免费视频制作网站,更新又快又好的免费电影网站?  如何在建站宝盒中设置产品搜索功能?  成都响应式网站开发,dw怎么把手机适应页面变成网页?  ,柠檬视频怎样兑换vip?  高性能网站服务器部署指南:稳定运行与安全配置优化方案  建站主机解析:虚拟主机配置与服务器选择指南  购物网站制作费用多少,开办网上购物网站,需要办理哪些手续?  电商平台网站制作流程,电商网站如何制作?  如何通过NAT技术实现内网高效建站?  seo网站制作优化,网站SEO优化步骤有哪些?  矢量图网站制作软件,用千图网的一张矢量图做公司app首页,该网站并未说明版权等问题,这样做算不算侵权?应该如何解决?  电商网站制作公司有哪些,1688网是什么意思?  长沙做网站要多少钱,长沙国安网络怎么样?  制作网站的公司有哪些,做一个公司网站要多少钱?  潮流网站制作头像软件下载,适合母子的网名有哪些?  如何在自有机房高效搭建专业网站?  东莞专业网站制作公司有哪些,东莞招聘网站哪个好?  如何访问已购建站主机并解决登录问题?  家具网站制作软件,家具厂怎么跑业务?  西安制作网站公司有哪些,西安货运司机用的最多的app或者网站是什么?  建站之星免费模板:自助建站系统与智能响应式一键生成  怀化网站制作公司,怀化新生儿上户网上办理流程?  如何通过服务器快速搭建网站?完整步骤解析  如何挑选优质建站一级代理提升网站排名?  家族网站制作贴纸教程视频,用豆子做粘帖画怎么制作?  如何登录建站主机?访问步骤全解析  实现虚拟支付需哪些建站技术支撑?  如何通过二级域名建站提升品牌影响力?  如何选择CMS系统实现快速建站与SEO优化?  网站制作需要会哪些技术,建立一个网站要花费多少?  学校为何禁止电信移动建设网站?  成都网站制作公司哪家好,四川省职工服务网是做什么用?  如何在Windows虚拟主机上快速搭建网站?  常州自助建站:操作简便模板丰富,企业个人快速搭建网站  如何通过PHP快速构建高效问答网站功能?  实例解析Array和String方法  哈尔滨网站建设策划,哈尔滨电工证查询网站?  mc皮肤壁纸制作器,苹果平板怎么设置自己想要的壁纸我的世界?  建站主机功能解析:服务器选择与快速搭建指南  C#如何使用XPathNavigator高效查询XML  c# Task.ConfigureAwait(true) 在什么场景下是必须的  建站主机默认首页配置指南:核心功能与访问路径优化  网站按钮制作软件,如何实现网页中按钮的自动点击?  上海网站制作网站建设公司,建筑电工证网上查询系统入口?  如何彻底卸载建站之星软件?  JS中使用new Date(str)创建时间对象不兼容firefox和ie的解决方法(两种)  教学网站制作软件,学习*后期制作的网站有哪些?  建站之星导航配置指南:自助建站与SEO优化全解析  专业网站制作企业网站,如何制作一个企业网站,建设网站的基本步骤有哪些?  建站之星后台密码如何安全设置与找回? 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。