Sobes.tech
Назад к вопросам
Junior — Middle
89

В каких ситуациях может возникнуть взаимоблокировка потоков или процессов?

Компании, где спрашивали
Lamoda Tech
Twinby

Ответ от нейросети

sobes.tech AI

Взаимоблокировка (deadlock) возникает, когда два или более потоков или процессов одновременно ждут освобождения ресурсов, занятых друг другом, и ни один из них не может продолжить работу. Основные ситуации, приводящие к взаимоблокировке:

  • Потоки захватывают несколько ресурсов в разном порядке. Например, поток A захватил ресурс 1 и ждёт ресурс 2, а поток B захватил ресурс 2 и ждёт ресурс 1.
  • Использование блокировок (mutex) без строгого порядка захвата.
  • Циклическое ожидание ресурсов.

В Go это может произойти при неправильном использовании мьютексов, каналов или других синхронизирующих примитивов. Например, если два горутины ждут друг друга через каналы без таймаутов или буферов.

Чтобы избежать взаимоблокировок, нужно:

  • Захватывать ресурсы в одном и том же порядке.
  • Использовать таймауты или попытки захвата с возвратом ошибки.
  • Минимизировать время удержания блокировок.

Пример простой взаимоблокировки с мьютексами в Go:

var mu1, mu2 sync.Mutex

func goroutine1() {
    mu1.Lock()
    defer mu1.Unlock()
    time.Sleep(time.Millisecond * 100)
    mu2.Lock()
    defer mu2.Unlock()
    // работа
}

func goroutine2() {
    mu2.Lock()
    defer mu2.Unlock()
    time.Sleep(time.Millisecond * 100)
    mu1.Lock()
    defer mu1.Unlock()
    // работа
}

Здесь goroutine1 и goroutine2 могут взаимно блокироваться, если первая захватила mu1, а вторая — mu2, и обе ждут освобождения другого мьютекса.