Как устроен sync.Mutex
Вопрос
Расскажите, как устроен sync.Mutex внутри: быстрый путь, спин, режим голодания.
Попробуйте сами
Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.
Показать ответ и разбор
Коротко
Что должно прозвучать в ответе
Состояние в одном int32: locked, woken, starving и счётчик ждущих
Быстрый путь: CAS 0 → locked без захода в рантайм
Медленный путь: короткий спин на многоядерной машине, затем парковка на семафоре
Нормальный режим: разбуженный конкурирует с новыми горутинами, новые часто выигрывают
Режим голодания после ожидания больше 1 мс: владение передаётся напрямую первому в очереди
Выход из режима голодания, когда очередь пуста или ждали меньше 1 мс
Что могут спросить следом
- Почему в нормальном режиме новым горутинам выгоднее отдавать мьютекс?
- Чем RWMutex отличается внутри?
Разбор
Mutex это две переменные: state и sema. В state упакованы бит locked, бит woken, бит starving и число ждущих. Быстрый путь Lock: одна CAS из 0 в locked, без вызова рантайма, поэтому незахваченный мьютекс очень дешёвый. Если занято, горутина немного крутится (спин), но только на многоядерной машине, при свободных P и пока мьютекс не в режиме голодания: держатель может скоро отпустить. Потом горутина паркуется на семафоре рантайма. В нормальном режиме разбуженная горутина соревнуется с новыми, которые уже на процессоре, и часто проигрывает: это выгодно для пропускной способности, потому что не нужно переключать контекст. Но так ждущая может голодать, поэтому если горутина ждёт больше 1 мс, мьютекс переходит в режим голодания: Unlock передаёт владение прямо первой в очереди, новые не спинят и встают в хвост. Режим выключается, когда получившая мьютекс горутина последняя в очереди или ждала меньше 1 мс.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.
Ещё по теме «sync и атомики»
- Глобальный максимум через CompareAndSwap
- Конкурентные переводы между счетами без дедлока
- Шардированная мапа с мьютексом на шард
- Что выведет Go: atomic.Int64 из 100 горутин
- Что выведет Go: sync.Once и OnceValue
- Код-ревью Go: кеш на RWMutex
- Код-ревью Go: ленивый синглтон и горячая перезагрузка конфига
- Типизированные атомики