Group.Wait()
блокируется до тех пор, пока не будут возвращены все вызовы функций из метода Group.Go()
, так что это точка синхронизации.Это гарантирует, что performAction(one, two)
не запустится до того, как будут выполнены записи в one
и two
, поэтому в вашем примере мьютекс не нужен.
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)
Если вы хотите получить доступ к one
и two
из других программ, в то время как программы, которые их пишут, работают одновременно, тогда да, вам нужно заблокировать их, например:
// 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
, а в программе, которая их читает, RWMutex.RLock()
и RWMutex.RUnlock()
также будет достаточно.