我有以下功能可以旋转一定数量的go例程
func (r *Runner) Execute() {
var wg sync.WaitGroup
wg.Add(len(r.pipelines))
for _, p := range r.pipelines {
go executePipeline(p, &wg)
}
wg.Wait()
errs := ....//contains list of errors reported by any/all go routines
}
我当时认为渠道可能有某种方式,但我似乎无法弄明白。
答案 0 :(得分:0)
如果可以使executePipeline返回错误,可以使用互斥锁:
// ...
for _, p := range r.pipelines {
go func(p pipelineType) {
if err := executePipeline(p, &wg); err != nil {
mu.Lock()
errs = append(errs, err)
mu.UnLock()
}
}(p)
}
要使用频道,您可以为错误添加单独的goroutine列表:
errCh := make(chan error)
go func() {
for e := range errCh {
errs = append(errs, e)
}
}
并在Execute
函数中进行以下更改:
// ...
wg.Add(len(r.pipelines))
for _, p := range r.pipelines {
go func(p pipelineType) {
if err := executePipeline(p, &wg); err != nil {
errCh <- err
}
}(p)
}
wg.Wait()
close(errCh)
如果goroutines的数量不高,你可以随时使用上面列出的@zerkms方法。
而不是从executePipleline
返回错误并使用匿名函数包装器,您总是可以在函数本身内进行上述更改。
答案 1 :(得分:0)
您可以使用@Kaveh Shahbazian建议的频道:
func (r *Runner) Execute() {
pipelineChan := makePipeline(r.pipelines)
for cnt := 0; cnt < len(r.pipelines); cnt++{
//recieve from channel
p := <- pipelineChan
//do something with the result
}
}
func makePipeline(pipelines []pipelineType) <-chan pipelineType{
pipelineChan := make(chan pipelineType)
go func(){
for _, p := range pipelines {
go func(p pipelineType){
pipelineChan <- executePipeline(p)
}(p)
}
}()
return pipelineChan
}
请参阅此示例:https://gist.github.com/steven-ferrer/9b2eeac3eed3f7667e8976f399d0b8ad