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

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

Barbara Streisand
Barbara Streisand原创
2024-11-27 04:57:14348浏览

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中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn