Мьютекс или канал
Вопрос
Когда вы используете мьютекс, а когда каналы? Приведите примеры.
Попробуйте сами
Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.
Показать ответ и разбор
Коротко
Что должно прозвучать в ответе
Каналы: передача данных и владения, конвейеры, сигналы завершения
Мьютекс: защита общего состояния (кеш, счётчики, мапа)
Атомики: одиночные счётчики и флаги, горячая замена конфига
Правило «share memory by communicating», но без фанатизма
Критерий: что проще читать и проверить; минимальная критическая секция
Проверка через -race и тесты
Что могут спросить следом
- Почему счётчик через канал хуже атомика?
- Как вы защищаете мапу, которую часто читают и редко пишут?
Разбор
Если данные передаются из рук в руки, например задачи воркерам или результаты стадий конвейера, беру канал: он выражает передачу владения, и после отправки данными владеет получатель. Каналы же для сигналов: закрыть done, чтобы остановить всех. Если несколько горутин читают и меняют одно состояние, например кеш в памяти или мапу сессий, беру мьютекс: это короче, понятнее и быстрее, чем гонять запросы через канал в горутину-владельца. Для одиночного счётчика метрик или флага достаточно атомика, а atomic.Pointer удобен для горячей замены конфига. Критическую секцию держу маленькой и не делаю под мьютексом ввод-вывод. Счётчик через канал хуже атомика на порядки: каждая операция это синхронизация и переключение горутин. Любой вариант проверяю тестами под -race.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.
Ещё по теме «sync и атомики»
- Глобальный максимум через CompareAndSwap
- Конкурентные переводы между счетами без дедлока
- Шардированная мапа с мьютексом на шард
- Что выведет Go: atomic.Int64 из 100 горутин
- Что выведет Go: sync.Once и OnceValue
- Код-ревью Go: кеш на RWMutex
- Код-ревью Go: ленивый синглтон и горячая перезагрузка конфига
- Типизированные атомики