Материал проходит вычитку — возможны неточности.
Урок 90 из 118

Дизайн критических секций

После ночного дедлока Сергей попросил пересмотреть все критические секции конвейера. На ревью Аня оставила один общий комментарий: секция закрывала ровно одну логическую операцию — ничего лишнего внутри. Миша переписал секции по этому правилу, и они стали заметно короче.

Главная мысль

критическая секция должна быть короткой, а гранулярность блокировок — по инвариантам данных: блокируй то, что меняешь, и не держи мьютекс во время долгих операций.

Не держать мьютекс во время долгой операции

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
Задание · вопросы

Проверьте себя

Вопрос 1 из 2

Форматирование строки стоит под мьютексом. В чём проблема?

Вопрос 2 из 2

Как выбирать гранулярность блокировок?

Итоги

Короткие секции, гранулярность по инвариантам, никаких долгих операций под мьютексом. Мьютекс — про согласованность данных, а не про «защитить код».

Наш сайт собирает куки. Чтобы тебе было удобнее им пользоваться. Нажимая на кнопку, ты даёшь разрешение собирать куки