go - 在 Go 中使用 WaitGroup 和 channel

标签 go concurrency goroutine

我正在使用调用许多 Web 服务的 Go 开发 cargo 服务,但我不确定如何实现并发模型。这种方法刚刚奏效,但有时它会锁定。我相信 channel 和 WaitGroup 存在一些问题。我真的需要使用 WaitGroups 或者只有 channel 才能锁定例程。

// Call carriers quote webservice
var wg sync.WaitGroup
error := make(chan error)
quote := make(chan []freight.Quote)
for _, c := range carriers {
    go c.Quote(&wg, obj, quote, error)
}
wg.Wait()

// Collect the results
quotes:= make([]freight.Quote, 0)
for i := 1; i < len(carriers); i++ {
    err := <-error
    quoteAws:= <-quote

    if err != nil {
        log.Println(err)
    }
    if quoteAws != nil {
        quotes= append(quotes, quoteAws...)
    }
}
close(error)
close(quote)

func (carrier CarrierA) Quote(wg *sync.WaitGroup, obj Volume, quotes chan []Quote, err chan error) 
{
    // Deal with waitgroup
    wg.Add(1)
    defer wg.Done()
    
    // Quote the freigth
    err <- nil
    quotes <- quotesResult
    return
}

最佳答案

使用 slice 来收集错误和引号。使用 WaitGroup 来等待 goroutine 完成。

errs := make([]error, len(carriers))
quotes := make([]freight.Quote, len(carriers))
var wg sync.WaitGroup
for i, c := range carriers {
    wg.Add(1)
    go func(i int, c Carrier) {
        defer wg.Done()
        quotes[i], errs[i] = c.Quote(args)
    }(i, c)
}
wg.Wait()

关于go - 在 Go 中使用 WaitGroup 和 channel ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63366250/

相关文章:

string - 将 int 转换为十六进制字符串然后在 Golang 中用 0 填充它的有效方法?

c++ - 与宽松的原子同步

iphone - 可以从其他后台线程启动后台线程吗? (NSObj)

csv - 在 Go 中将 CSV 记录解码为结构

go - f.Type()= ="string"直接用golang reflect怎么办?

java - 为什么此方法引发IllegalMonitorStateException?

Go,将数据传递到 channel

go - 如何在递归函数中设置mutex和sync.waitgroup?

go - 是否可以取消未完成的 goroutines?

json - 在 golang 中解码平面和嵌套的 json