如果 Goroutine 完成并关闭错误通道,如何捕获?

How to cacth if Goroutine finished and close error channel?

在下面的代码片段中,我试图循环一些数据并为每次迭代启动新的 go 例程。我已经创建了错误通道,如果 goroutine 出现一些错误,它应该将其写入通道。所以我有两个问题:

  1. 如果所有 goroutine 都完成并关闭错误通道以中断“for”循环以继续执行主函数,如何捕获?
  2. 如果在每个例程中我将调用一些将值附加到全局变量的函数,是否会出现竞争条件问题?如果是,如何处理。
package main

import (
    "fmt"
)

var errc = make(chan error, 15)


func fetchAll() {
    var N = 15
    for i := 0; i < N; i++ {
        go func(i int) {
            err := error(nil)
            if err != nil {
                errc <- err
            }
            // Doing some stuff there
            fmt.Println(i)
        }(i)
    }
}

func main() {
    fetchAll()
    for {
        select {
        case err := <-errc:
            fmt.Println(err)
            break
        }
    }
    fmt.Println("Finished All")

}

使用等待组:

wg:=sync.WaitGroup{}
for i := 0; i < N; i++ {
    wg.Add(1)
    go func(i int) {
       defer wg.Done()
       err := error(nil)
       if err != nil {
           errc <- err
       }
       // Doing some stuff there
       fmt.Println(i)
    }(i)
}
go func() {
   wg.Wait()
   close(errc)
}

然后你可以改变main中的循环。该循环将在通道关闭时终止。

for err:=range errc {
  fmt.Println(err)
}

如果您在 goroutine 之间共享变量,请使用在 goroutine 之间共享的 sync.Mutex 来控制 read/write 这些变量,否则您将 运行 进入竞争条件。