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

sync.Cond †

В старой части сервиса, которая ещё обслуживала старые пакеты, Миша наткнулся на sync.Cond — механизм ожидания, о котором он только читал. Он разобрал, как тот работал, и убедился: в новом коде команды ему места не было.

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

Cond — условная переменная поверх мьютекса: горутина засыпает до Signal/Broadcast; в большинстве случаев хватает канала, и Cond нужен редко.

Механизм

var (
    mu   sync.Mutex
    cond = sync.NewCond(&mu)
)

// ожидающий:
mu.Lock()
for !ready {
    cond.Wait() // разблокирует мьютекс, спит; при пробуждении — снова захватывает
}
mu.Unlock()

// уведомляющий:
mu.Lock()
ready = true
cond.Broadcast() // или Signal — разбудить одного
mu.Unlock()

Wait требует удерживаемый мьютекс: он временно отдаёт его, спит, а при пробуждении захватывает снова. Signal будит одну горутину, Broadcast — всех. Проверка условия — всегда в цикле: пробуждение не гарантирует, что условие всё ещё верно (ложные пробуждения и гонки).

Почему Cond — редкость

Для «жди, пока условие станет верным» почти всегда хватает канала: закрой его — и все проснулись. Cond нужен, когда условие сложное и его нужно перепроверять под мьютексом — например, ожидание «буфер не пуст и не полон» в классических реализациях очередей. Такие задачи в прикладном коде редки.

Правило выбора

Начни с канала или мьютекса. Cond бери, только когда: условие проверяется под мьютексом, пробуждение должно быть выборочным (Signal, не всем) и перепроверка в цикле — естественная часть логики. Во всех остальных случаях Cond — усложнение без выгоды.

В следующем уроке

Вы узнаете:

  • почему проверка условия в цикле обязательна
  • как устроен ограниченный буфер на Cond
Задание · вопросы

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

Вопрос 1 из 3

Что делает cond.Wait() с мьютексом?

Вопрос 2 из 3

Почему условие ожидания проверяют в цикле for, а не в if?

Вопрос 3 из 3

Когда Cond нужен вместо канала?

Итоги

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

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