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

Конкурентный доступ к map

Прод упал с фатальной ошибкой времени выполнения — два шага конвейера одновременно писали в общий индекс файлов. Перезапуск падение не повторил: такая гонка ловилась не всегда, и ошибка могла не появиться вовсе. Индекс закрыли замком, и падения прекратились.

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

карта безопасна для чистого конкурентного чтения, но не для записи: запись или пара «чтение плюс запись» из нескольких горутин — гонка данных, которую рантайм может прервать фатальной ошибкой, но не обязан обнаружить; запись защищают мьютексом, а sync.Map — только для особых случаев.

Concurrent map writes

Go

Это не паника, а фатальная ошибка времени выполнения: она не перехватывается recover и завершает процесс. Но диагностика не гарантирована: детект рантайма вероятностный — ошибка может выскочить при первом же запуске, а может не выскочить никогда, и программа молча испортит данные. Поэтому в тестах гонку не поймать без race detector'а, да и -race ловит только пройденные пути. Гонка «чтение плюс запись» небезопасна точно так же, хотя в сообщении рантайма фигурирует только запись.

Защита мьютексом

Go

Мьютексы — отдельный урок, здесь зафиксируй правило: карта не потокобезопасна для записи — любая запись, а также смешанный доступ «чтение плюс запись» из нескольких горутин требуют внешней синхронизации. Чистое конкурентное чтение без записей безопасно и блокировок не требует (go.dev/doc/faq#atomic_maps).

Sync.Map — для особых случаев

sync.Map — потокобезопасная карта, но она не «просто карта с мьютексом». Она выигрывает в двух сценариях: ключ пишется один раз, а читается много (кэш конфигурации), и когда разные горутины работают с разными ключами. В обычных случаях документация рекомендует обычную map с блокировкой: она проще, а выигрыш sync.Map узкий — его подтверждают бенчмарком. Подробно — в уроке.

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

Вы узнаете:

  • почему concurrent map writes — fatal, а не panic
  • как race detector ловит гонку в тестах
Задание · вопросы

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

Вопрос 1 из 3

Две горутины одновременно пишут в одну map. Что может произойти?

Вопрос 2 из 3

Когда sync.Map действительно выигрывает?

Вопрос 3 из 3

Чистое конкурентное чтение map без записей — безопасно?

Итоги

Карта безопасна для чистого конкурентного чтения; запись и смешанный доступ «чтение плюс запись» — гонка, которую рантайм может прервать fatal error, но не обязан поймать. Защита записи — map + RWMutex; sync.Map — только для сценариев «пишем редко, читаем часто».

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