我试图找出一个例程遇到错误时立即报告错误的基本模式。
func doSomeWork(num int, errChan chan <- error) {
if num >= 10 {
errChan <- errors.New("Greater than 10")
}
return
}
const numWorkers int = 25
func run() error {
var wg sync.WaitGroup
errChan := make(chan error)
for i := 0; i < numWorkers; i++ {
wg.Add(1)
go func(num int) {
defer wg.Done()
doSomeWork(num, errChan)
}(i)
}
go func() {
wg.Wait()
close(errChan)
}()
err, ok := <-errChan
if !ok {
return nil
}
return err
}
字符串
这和预期的一样,当numWorkers = 10时,它返回nil< 10 and error when numworker is >。我实际上并不关心工人的数量,这只是一个简单的例子。但是,它感觉不是很习惯,当一个例程失败时,可能会有一些例程泄漏,因为其他例程仍然在运行,等待所有例程的例程也仍然在运行。有没有更习惯的方法来做到这一点,一旦一个例程失败,它也会停止所有例程?
1条答案
按热度按时间zlhcx6iw1#
代码是封闭的,但是当发送多个错误时会泄漏goroutine。第一个发送
errChan
的worker会退出,因为主goroutine会接收到这个值。所有发送到errChan
的worker会永远阻塞,因为没有goroutine接收这个值。wg.Wait(); close(errChan)
goroutine也会永远阻塞,等待worker完成。修复是双重的:使用非阻塞发送到通道,并确保
errChan
可以接收至少一个值。请参阅下面的评论以了解更多详细信息:
字符串
Run the program on the Playground!