Что происходит с горутинами при блокировке на запись mutex
Что проверяют
Понимаете ли, что блокируется горутина, а не поток операционной системы, и знаете ли про два режима работы sync.Mutex. Вопрос на понимание планировщика, а не на знание названий методов.
Как отвечать
Когда Lock не удаётся взять сразу, горутина сначала немного крутится вхолостую, это делается только на многоядерной машине и только когда ожидание обещает быть коротким, а затем паркуется рантаймом на семафоре. Ключевое: поток при этом не блокируется, планировщик снимает горутину и отдаёт поток другой готовой к работе. Именно поэтому ожидание на мьютексе стоит дёшево.
Про режимы стоит рассказать самому:
- обычный режим: разбуженная горутина конкурирует за мьютекс с теми, кто подошёл только что, и часто проигрывает, потому что новички уже на процессоре. Пропускная способность выше, справедливости нет;
- режим голодания: если горутина прождала дольше миллисекунды, мьютекс переключается, и
Unlockпередаёт владение напрямую первому в очереди, а новые не пытаются перехватить и встают в хвост.
Добавьте важные свойства. sync.Mutex не реентерабельный: повторный Lock в той же горутине это гарантированный дедлок. Владельца у него нет, разблокировать может другая горутина, а Unlock незаблокированного мьютекса роняет процесс фатальной ошибкой, которую не перехватить через recover.
Где спотыкаются
Считают, что ожидающая горутина жжёт процессорное время в цикле. Холостое кручение занимает единицы микросекунд, дальше горутина спит и не потребляет ничего. Обратная ошибка тоже встречается: думают, что на каждой ждущей горутине висит поток.
Второе: копируют структуру, внутри которой лежит мьютекс. Метод с получателем по значению, передача структуры в функцию, укладка в срез: получаются независимые копии, и защиты больше нет. Это ловит go vet, если смотреть его вывод.
Третье: ставят sync.RWMutex везде, где чтений больше, чем записей. На коротких критических секциях он медленнее обычного, а вложенный захват на чтение внутри такого же захвата даёт дедлок, если между ними успел встать пишущий.