【发布时间】:2023-03-27 20:45:01
【问题描述】:
这是我提到的代码:
// this is inside some method which has return signature like this: (*Data, error)
mapStore := make(...)
resSlice := make(...)
wg := new(sync.WaitGroup)
ec := make(chan error)
for keyString, sliceValue := range myMap {
wg.Add(1)
keyString := keyString
sliceValue := sliceValue
go func() {
err := func(keyString string, sliceValue []Value, wg *sync.WaitGroup) error {
defer wg.Done()
res, err := process(keyString, sliceValue)
if err != nil {
return errors.Wrapf(err, "wrong")
}
if res == nil {
return nil
}
if res.someData != nil {
mapStore[*res.someData] = append(mapStore[*res.someData], res)
return nil
}
resSlice := append(resSlice, res)
return nil
}(keyString, sliceValue, wg)
if err != nil {
ec <- err
return
}
}()
}
}
wg.Wait()
select {
case err := <- ec:
return nil, err
default:
return resSlice, nil
}
我被告知由于某种原因这不是线程安全的,但我不确定在哪里。我认为这是处理ec 中的错误的问题,但希望得到一些帮助!
【问题讨论】:
-
你能提供一个minimum reproducible example吗?这个 sn-p 缺少很多有助于调试的信息。我怀疑你的问题是当你这样做
mapStore[*res.someData]时,你正在修改一个你也在多个 go-routines 中迭代的地图。 -
变量
mapStore和resSlice同时修改。 -
任何时候你认为存在并发问题但你不知道在哪里,that's what the race detector is for。
标签: go parallel-processing thread-safety channel goroutine