gpt4 book ai didi

go - 我们应该在 goroutine 中同步变量赋值吗?

转载 作者:IT王子 更新时间:2023-10-29 02:30:53 25 4
gpt4 key购买 nike

假设我声明了两个映射并想将其分配到错误组中的两个不同的 goroutine 中。我不执行任何读/写。我应该用 lock 保护分配操作还是可以忽略它?

UPD3:在Java Concurrency In Practice Brian Goetz's第一部分第 3 章共享对象,提到:

Locking is not just about mutual exclusion; it is also memory visibility. To ensure that all threads see the most up-to-date values of shared mutable variables, the reading and writing threads must synchronize on a common lock.

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 个 goroutines - parent 和错误组中的两个。无法保证我们的父 goroutine 共享内存在 errgroup goroutines 完成后获得最后更新,直到我们用内存屏障包装对共享内存的访问

最佳答案

Group.Wait()阻塞直到来自 Group.Go() 的所有函数调用方法已经返回,所以这是一个同步点。这确保 performAction(one, two) 不会在对 onetwo 的任何写入完成之前开始,因此在您的示例中不需要互斥锁.

g, gctx := errgroup.WithContext(ctx)
g.Go(func() error {
// ...
one = resp.One
return nil
})

g.Go(func() error {
// ...
two = resp.Two
return nil
})

if err := g.Wait(); err != nil {
return err
}
// Here you can access one and two safely:
performAction(one, two)

如果您要从其他 goroutine 访问 onetwo 而编写它们的 goroutines 同时运行,那么是的,您需要锁定它们,例如:

// This goroutine runs concurrently, so all concurrent access must be synchronized:
go func() {
mu.Lock()
fmt.Println(one, two)
mu.Unlock()
}()

g, gctx := errgroup.WithContext(ctx)
g.Go(func() error {
// ...
mu.Lock()
one = resp.One
mu.Unlock()
return nil
})

g.Go(func() error {
// ...
mu.Lock()
two = resp.Two
mu.Unlock()
return nil
})

if err := g.Wait(); err != nil {
return err
}
// Note that you don't need to lock here
// if the first concurrent goroutine only reads one and two.
performAction(one, two)

另请注意,在上面的示例中,您可以使用 sync.RWMutex ,并在读取它们的 goroutine 中,RWMutex.RLock()RWMutex.RUnlock()也足够了。

关于go - 我们应该在 goroutine 中同步变量赋值吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55237513/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com