Синхронный доступ к общей map в Go

Приведённый код уже защищает map с помощью одного RWMutex. При доступе только через эти функции ошибки concurrent map read and map write быть не должно.

Короткий ответ

Что ответить на собеседовании

Приведённый код уже защищает map с помощью одного RWMutex. При доступе только через эти функции ошибки concurrent map read and map write быть не должно.

Подробный разбор

Ответ с пояснениями

Условие

В программе объявлена глобальная карта map[string]int, к которой из разных горутин одновременно выполняются операции чтения и записи. При этом приложение падает с ошибкой fatal error: concurrent map read and map write. Необходимо подобрать подходящий механизм синхронизации, который устранит эту проблему.

package main

import (
 "fmt"
 "sync"
 "time"
)

var (
 mu sync.RWMutex
 m  = map[string]int{"a": 1}
)

func main() {
 go read()
 time.Sleep(1 * time.Second)
 go write()
 time.Sleep(1 * time.Second)
}

func read() {
 for {
  mu.RLock()
  fmt.Println(m["a"])
  mu.RUnlock()
 }
}

func write() {
 for {
  mu.Lock()
  m["a"] = 2
  mu.Unlock()
 }
}

Ответ

Приведённый код уже защищает map с помощью одного RWMutex. При доступе только через эти функции ошибки concurrent map read and map write быть не должно.

Чтение выполняется между RLock/RUnlock, запись — между Lock/Unlock. Если авария остаётся, ищите другие обращения к m без того же mutex или копирование объекта синхронизации.

Улучшите read: скопируйте значение под read-lock, снимите его и только затем вызывайте Println, чтобы медленный вывод не удерживал блокировку. Бесконечные циклы создают нагрузку; добавьте управляемое завершение через context и ожидание работников вместо Sleep в main. Порядок конкретных значений 1 и 2 не следует использовать как синхронизацию.

ИИ-помощник для собеседований

Хочешь уверенно проходить собеседования?

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

Подробнее