В Go отображения (map) не являются потокобезопасными по умолчанию. Если несколько горутин одновременно записывают или читают одну и ту же map без синхронизации, возникнет состояние гонки (data race), приводящее к панике fatal error: concurrent map read and map write или повреждению данных.
Для потокобезопасной работы с map необходимо:
sync.Map, который предназначен для высоконагруженных конкурентных сценариев.var mu sync.RWMutex m := make(map[string]int) // Запись mu.Lock() m["key"] = 1 mu.Unlock() // Чтение mu.RLock() v := m["key"] mu.RUnlock() // Либо sync.Map var sm sync.Map sm.Store("key", 1) v, _ := sm.Load("key")
Почему одновременное чтение и запись из разных горутин в map в Go так опасны, если map — это встроенный тип?
Ответ: В Go встроенный тип map не предоставляет синхронизации. Одновременное обращение к map из нескольких горутин вызывает не просто некорректные значения, а может привести к краху программы. Даже одновременное чтение и запись (когда нет пересекающихся ключей!) может вызвать фатальную ошибку. Это отличается от некоторых других языков, в которых коллекции «терпимы» к конкурентным обращениям.
История
В реальном проекте разработчик использовал глобальную map для кэширования данных. Сервис работал стабильно на тестах, но на нагрузочных тестах и в продакшене начал падать с ошибкой fatal error: concurrent map read and map write. Причиной был параллельный доступ к map из разных http-запросов без использования Mutex.
История
В веб-приложении Go один программист решил улучшить производительность и использовал обычную map в качестве пулла коннектов, предполагая, что многопоточность обеспечивается фреймворком. При резком росте трафика сервис начал падать без явной причины: из-за гонки данные в map повреждались и возникали паники.
История
Во внутреннем сервисе Go приложение использовало map для сбора статистики «на лету», считая, что основное обращение идёт только на запись. На самом деле другая часть кода периодически запрашивала данные для построения отчетов, что приводило к трудноуловимым падениям только раз в сутки — как раз когда срабатывала статистика. Анализ показал, что чтения и записи перекрывались без какой-либо блокировки.