Когда использовать каналы, а когда sync.Mutex и WaitGroup?
- Чем Mutex отличается от RWMutex?
- Как дождаться завершения нескольких горутин?
Каналы — для передачи данных и владения ими между горутинами (конвейеры, очереди задач). Mutex — для защиты общего состояния (кэш, счётчик). WaitGroup — дождаться группы горутин. RWMutex — много читателей одновременно или один писатель.
- wg.Add до запуска горутины, defer wg.Done() внутри
- Мьютекс не копировать — передавать структуру по указателю
- sync.Once — однократная инициализация; atomic — простые счётчики
А ещё errgroup.Group — WaitGroup с первой ошибкой и отменой контекста
Подробно
Правило выбора. Если данные передаются от одной горутины другой — канал. Если несколько горутин разделяют структуру — мьютекс: канал ради защиты карты получается сложнее и медленнее.
WaitGroup: Add(n) до запуска, Done() в каждой горутине (через defer), Wait() блокируется до нуля. Ошибка — Add внутри горутины: Wait может вернуться раньше. В Go 1.25 появился wg.Go(f).
errgroup (golang.org/x/sync) — запускает горутины, ждёт всех и возвращает первую ошибку; с WithContext отменяет остальных.
Атомики (sync/atomic, типы atomic.Int64) — для счётчиков и флагов без мьютекса.
Пример
type Cache struct {
mu sync.RWMutex
m map[string]string
}
func (c *Cache) Get(k string) (string, bool) {
c.mu.RLock(); defer c.mu.RUnlock()
v, ok := c.m[k]; return v, ok
}
var wg sync.WaitGroup
for _, url := range urls {
wg.Add(1)
go func() { defer wg.Done(); fetch(url) }()
}
wg.Wait()Что хотят услышать
- Критерий: передача данных или общее состояние.
- Правильное использование WaitGroup.
- RWMutex, Once, errgroup.
Проверьте себя
Один верный вариант. Подумайте, потом откройте ответ.
Показать варианты и ответ
- ✗Мьютекс можно безопасно копировать вместе со структурой
- ✗wg.Add вызывают внутри запущенной горутины, чтобы не было гонки
- ✓Каналы — передача данных, Mutex — общее состояние
- ✗RWMutex позволяет нескольким писателям работать одновременно
Связанные вопросы
Разбор собеседования с sotto
После собеседования sotto разбирает разговор: оценка, каждый вопрос — хорошо, частично или слабо, чего не хватило в ответе и над чем поработать к следующему разу. Первые 30 минут бесплатно.