如何处理goroutine中的错误?

huangapple go评论108阅读模式
英文:

How to handle errors in goroutines?

问题

我正在尝试同时运行多个任务,并获取结果或错误。

// 数据通道
ch := make(chan int)
ch2 := make(chan int)
ch3 := make(chan int)

// 错误通道
errCh := make(chan error)
errCh2 := make(chan error)
errCh3 := make(chan error)

// 启动任务
go taskF(ch, errCh)
go taskF2(ch2, errCh2)
go taskF3(ch3, errCh3)

然后我开始检查每个错误。如果有任何错误,我们打印它;否则,我们打印每个任务的结果。

err := <-errCh
if err != nil {
print("we have an error")
return
}

err2 := <-errCh2
if err2 != nil {
print("we have an error 2")
return
}

err3 := <-errCh3
if err3 != nil {
print("we have an error 3")
return
}

然后,如果没有错误,我收集通过每个通道返回的值。

task := <-ch
task2 := <-ch2
task3 := <-ch3

print("task %v task2 %v task3 %v", task, task2, task3)

我想知道我是否做得对。我担心代码太冗长。我在考虑使用带缓冲的通道来处理错误,但我不知道如何检查所有的错误。我认为在goroutine中同步错误会很好,这样如果一个goroutine出现错误,其他goroutine就会停止,但我不知道如何以非阻塞的方式实现。

英文:

I'm trying to run several tasks concurrently and get the result or error back.

  1. //data channels
  2. ch := make(chan int)
  3. ch2 := make(chan int)
  4. ch2 := make(chan int)
  5. //error channels
  6. errCh := make(chan error)
  7. errCh2 := make(chan error)
  8. errCh3 := make(chan error)
  9. //functions
  10. go taskF(ch, errCh)
  11. go taskF2(ch2, errCh2)
  12. go taskF3(ch3, errCh3)

Then I start checking on each error. If there is any error we print it otherwise we print the result of each task

  1. err := &lt;-errCh
  2. if err != nil{
  3. print(&#39;we have an error &#39;)
  4. return
  5. }
  6. err2 := &lt;-errCh2
  7. if err2 != nil{
  8. print(&#39;we have an error 2&#39;)
  9. return
  10. }
  11. err3 := &lt;-errCh3
  12. if err3!= nil{
  13. print(&#39;we have an error 3&#39;)
  14. return
  15. }

Then if there is no error I collect the values returned though each channel

  1. task := &lt;-ch
  2. task2 := &lt;-ch2
  3. task3 := &lt;-ch3
  4. print(&quot;task %v task2 %v task3 %v&quot;, task, task2, task3)

I'm wondering if I'm doing it right. I'm worried that the code quite verbose. I was thinking to use buffered channels for errors but i can't figure it out how to check all the errors. I think it would also be nice to somehow sync the errors within the goroutines so that if there is an error on one goroutine the other goroutines would stop but I don't know any way to do in an unblocking manner.

答案1

得分: 1

考虑只使用一个通道进行同步,并且在该通道中包含一个错误状态(参见Result结构体)。每当接收到一个Result时,确保错误状态为nil。将每个任务封装在一个Task结构体中,这样当一个任务返回错误时,可以调用每个任务的Stop方法。根据您的具体应用程序,可能有更好的处理方式,比如使用WaitGroups(http://golang.org/pkg/sync/#WaitGroup)。

  1. type Result struct {
  2. Val int
  3. Err error
  4. }
  5. type Task struct {
  6. stopped bool
  7. }
  8. func (t *Task) Stop() {
  9. t.stopped = true
  10. }
  11. func (t *Task) Run(doneChan chan Result) {
  12. // 长时间运行的任务在这里
  13. // 定期检查t.stopped
  14. doneChan <- Result{Val: ..., Err: nil}
  15. }
英文:

Consider using only one channel for synchronization, and having this channel include an error state (see the Result struct). Whenever you receive a Result, make sure the error state is nil. Wrapping each task in a Task struct will allow you to call Stop on each task when one returns an error. Depending on your exact application there may be better ways to handle this, such as WaitGroups (http://golang.org/pkg/sync/#WaitGroup).

  1. type Result struct {
  2. Val int
  3. Err error
  4. }
  5. type Task struct {
  6. stopped bool
  7. }
  8. func (t *Task) Stop() {
  9. t.stopped = true
  10. }
  11. func (t *Task) Run(doneChan chan Result) {
  12. // long-running task here
  13. // periodically check t.stopped
  14. doneChan &lt;- Result{Val: ..., Err: nil}
  15. }

huangapple
  • 本文由 发表于 2014年4月6日 04:48:08
  • 转载请务必保留本文链接:https://go.coder-hub.com/22886598.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定