Назад к вопросам
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, и обе ждут освобождения другого мьютекса.