Что произойдет, если за RWMutex последует обычный Mutex

«Что произойдет, если за RWMutex последует обычный Mutex» — вопрос из категории Golang, который задают на 23% собеседований Golang Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Если после RWMutex поставить обычный Mutex, это может привести к взаимоблокировке (deadlock) в определенных сценариях.

Пример:

var (
    rwMu sync.RWMutex
    mu   sync.Mutex
)

func example() {
    rwMu.RLock() // Захватываем read lock
    defer rwMu.RUnlock()

    mu.Lock() // Блокируемся, если кто-то уже держит mu
    defer mu.Unlock()

    // Критическая секция
}

Проблема:
Если другая горутина сначала захватит mu, а затем попытается взять rwMu.Lock() (на запись), возникнет deadlock:

  • Горутина 1: RLock() → ждёт mu
  • Горутина 2: mu.Lock() → ждёт Lock() на RWMutex (который не даст его, пока есть ридеры).

Вывод:
Порядок блокировок должен быть согласованным, иначе возможна взаимоблокировка. Лучше избегать смешивания RWMutex и Mutex без четкой стратегии.