【发布时间】:2019-08-09 18:35:24
【问题描述】:
假设我声明了两个映射并希望将其分配到错误组中的两个不同的 goroutine 中。我不执行任何读/写。
我应该用lock 保护分配操作还是可以省略它?
UPD3:在Java Concurrency In PracticeBrian Goetz's Part I Chapter 3 Shared Objects,提到:
锁定不仅仅是互斥;也是记忆 能见度。确保所有线程都看到最新的值 共享可变变量,读写线程必须 在公共锁上同步。
var (
mu sync.Mutex
one map[string]struct{}
two map[string]struct{}
)
g, gctx := errgroup.WithContext(ctx)
g.Go(func() error {
resp, err := invokeFirstService(gctx, request)
if err != nil {
return err
}
mu.Lock()
one = resp.One
mu.Unlock()
return nil
})
g.Go(func() error {
resp, err := invokeSecondService(gctx, request)
if err != nil {
return err
}
mu.Lock()
two = resp.Two
mu.Unlock()
return nil
})
if err := g.Wait(); err != nil {
return err
}
// UPD3: added lock and unlock section
m.Lock()
defer m.Unlock()
performAction(one, two)
UPD:添加了更多关于变量的上下文
UPD2:我的疑虑是什么:我们有 3 个 goroutine - 父级和错误组中的两个。不能保证我们的父 goroutine 共享内存在 errgroup goroutine 完成后获得最后一次更新,直到我们用内存屏障包装对共享内存的访问
【问题讨论】:
标签: go concurrency synchronization locking