Дизайн критических секций
После ночного дедлока Сергей попросил пересмотреть все критические секции конвейера. На ревью Аня оставила один общий комментарий: секция закрывала ровно одну логическую операцию — ничего лишнего внутри. Миша переписал секции по этому правилу, и они стали заметно короче.
критическая секция должна быть короткой, а гранулярность блокировок — по инвариантам данных: блокируй то, что меняешь, и не держи мьютекс во время долгих операций.
Не держать мьютекс во время долгой операции
func (s *Store) LoadOrStore(key string, compute func() int) int {
s.mu.Lock()
if v, ok := s.m[key]; ok {
s.mu.Unlock()
return v
}
s.mu.Unlock()
v := compute() // долгое вычисление — БЕЗ мьютекса
s.mu.Lock()
s.m[key] = v
s.mu.Unlock()
return v
}
compute может звать сеть или диск. Держать мьютекс во время него — значит сериализовать всех остальных на секунды. Правило: секция — только обращения к данным, всё остальное — за её пределами. (Тонкость: между разблокировкой и повторным захватом значение могли вычислить дважды — для этого есть singleflight, урок.)
Гранулярность по инвариантам
Если структура хранит два независимых набора данных, один мьютекс на оба — грубо: обращение к первому блокирует обращения ко второму. Два мьютекса — по одному на набор — дают реальный параллелизм. Но дробить мьютексы до «по одному на поле» — перебор: если поля меняются всегда вместе, они — один инвариант, и мьютекс у них один.
Contention
Когда горутины часто сталкиваются на одном мьютексе (contention), сериализация съедает весь параллелизм: горутины стоят в очереди, ядра простаивают. Лечится тем же: короче секции, тоньше гранулярность, реже общий доступ — например, раздать каждой горутине свою ячейку слайса, как в уроках про WaitGroup.
Вы узнаете:
- как атомики заменяют мьютекс для одиночных значений
- как pprof mutex-профиль показывает contention
Проверьте себя
Форматирование строки стоит под мьютексом. В чём проблема?
Как выбирать гранулярность блокировок?
правильных ответов
Короткие секции, гранулярность по инвариантам, никаких долгих операций под мьютексом. Мьютекс — про согласованность данных, а не про «защитить код».
10 000 ₽ · 60 минут · онлайн