3 回答
TA贡献1829条经验 获得超9个赞
您的示例在使用 WaitGroups 方面没有任何明显错误。只要您调用wg.Add()
的数量与您启动的 goroutine 的数量相同,或者每次启动新的 goroutine 时都将其增加 1,这应该是正确的。
但是,您在 goroutine 中调用os.Exit
和panic
针对某些错误条件,因此如果您有多个这些正在运行,无论是否使用 WaitGroups,其中任何一个的失败都会终止所有这些。如果它在没有恐慌消息的情况下失败,我会看看这os.Exit(1)
条线。
defer wg.Done()
在函数开始时使用 go 也是一种很好的做法,这样即使发生错误,goroutine 仍然会减少其计数器。这样,如果 goroutine 之一返回错误,您的主线程将不会在完成时挂起。
TA贡献1906条经验 获得超3个赞
我会在您的示例中进行的一项更改是defer当您使用Done. 我认为这defer ws.Done()应该是您函数中的第一条语句。
我喜欢WaitGroup的简单。但是,我不喜欢我们需要传递对 goroutine 的引用,因为这意味着并发逻辑将与您的业务逻辑混合。
所以我想出了这个通用函数来为我解决这个问题:
// Parallelize parallelizes the function calls
func Parallelize(functions ...func()) {
var waitGroup sync.WaitGroup
waitGroup.Add(len(functions))
defer waitGroup.Wait()
for _, function := range functions {
go func(copy func()) {
defer waitGroup.Done()
copy()
}(function)
}
}
所以你的例子可以这样解决:
func imageDownloader(uri string, filename string) {
...
io.Copy(outFile, rd)
}
func main() {
functions := []func(){}
list := make([]Object, 5)
for _, object := range list {
function := func(obj Object){
imageDownloader(object.uri, object.filename)
}(object)
functions = append(functions, function)
}
Parallelize(functions...)
fmt.Println("Done")
}
如果你想使用它,你可以在这里找到它https://github.com/shomali11/util
- 3 回答
- 0 关注
- 213 浏览
添加回答
举报