今天,我一直在与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
我已尽力提供一个示例来说明我在说什么。循环将运行10次,doSomething()并且将waitGroup.Done()在每次迭代中调用,但是如果在所有此过程中发生错误(如所示),该someFunctionThatCanError()怎么办?
doSomething()
waitGroup.Done()
someFunctionThatCanError()
现在,当我尝试解决问题时,通过返回和/或取消通道,最终会导致死锁,因此我不确定从何处去。我也不确定如何处理我认为正在等待更多事情发生的WaitGroup。
任何帮助都非常感谢。
使用golang.org/x/sync/errgroup等待并处理goroutine中的错误。
package main import ( "errors" "log" "sync" "golang.org/x/sync/errgroup" ) var waitGroup sync.WaitGroup func main() { c := make(chan int, 10) var g errgroup.Group g.Go(func() error { return doSomething(c) }) // g.Wait waits for all goroutines to complete // and returns the first non-nil error returned // by one of the goroutines. if err := g.Wait(); err != nil { log.Fatal(err) } } func doSomething(c chan int) error { defer close(c) for i := 0; i < 10; i++ { n, err := someFunctionThatCanError() if err != nil { return err } c <- n } return nil } func someFunctionThatCanError() (int, error) { return 1, errors.New("an error") }
在操场上跑。