【发布时间】:2020-03-21 11:38:17
【问题描述】:
我想了解我围绕 WaitGroups 的逻辑是否正确,并看看是否有更有效的方式来构建我的代码。目的是尽可能快地执行任务。
我的代码填充了一个通过标准输入填充的_urls 频道。然后我启动了两个 WaitGroup,一个从这个 _urls 通道读取,另一个从一个 _downloads 通道读取,它是从第一个 WaitGroup 中的 goroutine 提供的。
基本上代码如下所示:
// declare channels
_urls := make(chan string)
_downloads := make(chan string)
// first waitgroup with 2 goroutines
var wg sync.WaitGroup
for i := 0; i < concurrency; i++ {
wg.Add(2)
go func() {
defer wg.Done()
for url := range _urls {
// perform GET request and inspect the responseBody
}
}()
go func() {
defer wg.Done()
for url := range _urls {
// perform a HEAD request to look for a certain file
// if the file exists, send to the _downloads channel
_downloads <- url
}
}()
}
// second waitgroup with 1 goroutine
var dwg sync.WaitGroup
for i := 0; i < concurrency; i++ {
dwg.Add(1)
go func() {
defer wg.Done()
for url := range _downloads {
// perform the download
}
}()
}
我关心的是这是否是提供_downloads 频道的有效方式,还是只在第一个 WaitGroup 中执行下载是否更有意义。
【问题讨论】:
-
我认为在您的示例中根本没有任何理由使用等待组。你添加它们的原因是什么?您也永远不会等待它们完成,因此在您的示例中它们是无操作的。
-
@Flimzy tbh 我在一些博客和其他 github 存储库中看到了类似的代码结构,因此假设它一定是正确的......
-
这可能是正确的,因为他们正在解决的问题。这并不意味着它适合您正在解决的问题。
-
我开始写一个详细的答案,但您的代码中没有足够的信息来提出正确的结构。完全不清楚您的前两个 goroutine(分别执行 GET 和 HEAD)如何相互关联,或与最终的 goroutine(执行下载)相关。但我认为这里根本没有理由使用等待组。
-
sync.WaitGroups 让您等到一定数量的独立事情发出信号完成。这就是关于 WaitGroups 的全部知识。它是关于等到一组事情完成。这是“最好的”、“最快的”还是“最惯用的”,很大程度上取决于实际问题。
标签: go concurrency goroutine