Этот вопрос проверяет знание примитивов для безопасной работы с конкурентными горутинами.
Синхронизация достижима через WaitGroup для ожидания завершения групп горутин, Mutex и RWMutex для защиты общих данных, Channel для обмена данными и сигнализации, а также atomic операции (sync/atomic) для безблокировочных счётчиков.
sync.WaitGroup:
var wg sync.WaitGroup
wg.Add(2)
go func() { defer wg.Done(); work() }()
go func() { defer wg.Done(); work() }()
wg.Wait()sync.Mutex / RWMutex:
var mu sync.Mutex
mu.Lock(); shared++; mu.Unlock()Channels:
Канал блокирует отправителя/получателя до готовности.
done := make(chan struct{})
go func() { work(); close(done) }()
<-donesync/atomic:
Безблокировочные инкременты:
atomic.AddInt64(&counter, 1)Вывод:
Выбирайте механизмы в зависимости от задач: блокировки для сложных структур, атомики для простых счётчиков, каналы для потоков данных.