今天,我一直在与Goroutines,Channels和WaitGroup一起玩耍,在阅读了一段时间之后,我终于开始理解这个概念。
我的问题是,我不确定在这样工作时如何处理错误,主要是因为我使用了WaitGroup。使用WaitGroup时,我首先添加将要执行的goroutine的数量,但是如果其中之一发生错误怎么办?
package main
import (
"errors"
"sync"
)
var waitGroup sync.WaitGroup
func main() {
c := make(chan int, 10)
waitGroup.Add(10)
go doSomething(c)
waitGroup.Wait()
}
func doSomething(c chan int) {
for i := 0; i < 10; i++ {
n, err := someFunctionThatCanError()
if err != nil {
// How do I end the routines and WaitGroups here?
}
c <- n
waitGroup.Done()
}
close(c)
}
func someFunctionThatCanError() (int, error) {
return 1, errors.New("an error")
}
操场:https://play.golang.org/p/ZLsBSqdMD49
我已尽力提供了一个示例来说明我在说什么。循环将在doSomething()
中运行10次,并且每次迭代都会调用waitGroup.Done()
,但是如果在所有这些迭代过程中都发生错误,该怎么办呢?
[当我现在尝试解决此问题时,通过返回和/或取消频道,我最终陷入了僵局,因此我不太确定从这里出发。我也不确定如何处理我认为正在等待更多事情发生的WaitGroup。
非常感谢您的帮助。
我修改了您的示例,我不知道这是否是一个干净的解决方案,但它避免了死锁等。
someFunctionThatCanError()
这里是func doSomething(c chan int) {
defer close(c)
for i := 0; i < 10; i++ {
n, err := someFunctionThatCanError(i)
if err != nil {
// How do I end the routines and WaitGroups here?
for j := i; j < 10; j++ {
waitGroup.Done()
}
return
}
c <- n
waitGroup.Done()
}
}
func someFunctionThatCanError(i int) (int, error) {
fmt.Println("running", i)
if i > 3 {
return 1, errors.New("an error")
}
return 1, nil
}
使用playground等待并处理goroutine中的错误。
golang.org/x/sync/errgroup