首页 > 后端开发 > Golang > 为什么我的 Gosync.WaitGroup 没有完成?

为什么我的 Gosync.WaitGroup 没有完成?

Barbara Streisand
发布: 2024-11-27 04:57:14
原创
304 人浏览过

Why Doesn't My Go sync.WaitGroup Ever Complete?

Golangsync.WaitGroup Never Completes

提供的代码通过获取 URL 列表并有条件地下载和保存文件到文件来演示并发性系统。主 goroutine 等待使用sync.WaitGroup 获取所有文件。但是,即使完成所有请求,程序也无法退出。

要理解此问题,请考虑 WaitGroup 的功能。它维护正在执行的 goroutine 的计数。如果计数达到零,waitgroup 立即返回,表明所有 goroutine 已完成执行。

在给定的代码中,WaitGroup 的 Add 方法用于增加计数,而 Done 方法用于减少计数。如果 Add 方法被调用的次数多于 Done 方法,反之亦然,WaitGroup 将永远不会达到零,导致主 goroutine 无限期等待。

提供的代码中有两个错误:

  1. downloadFromURL 函数接收 WaitGroup 的副本,而不是指向它的指针。这会导致 WaitGroup 内部数据的副本被传递,因此函数内对其进行的任何修改(例如调用 Done)对于主 goroutine 都是不可见的。要解决此问题,请将指针传递给 WaitGroup:
func main() {
    ...
    go downloadFromURL(url, &wg)
    ...
}
登录后复制
  1. defer wg.Done() 语句不会作为 downloadFromURL 函数中的第一个语句放置。如果在调用 Done 之前发生错误或执行任何其他逻辑,则递减操作将不会被注册,并且 WaitGroup 的计数永远不会达到零。要解决此问题,请确保 defer wg.Done() 是函数中的第一个语句:
func downloadFromURL(url string, wg *sync.WaitGroup) error {
    defer wg.Done()
    ...
}
登录后复制

完成这些更正后,WaitGroup 将正确运行,随着 goroutine 完成其计数而减少其计数任务,最终导致主协程成功退出。

以上是为什么我的 Gosync.WaitGroup 没有完成?的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板