В каких случаях может произойти дедлок?
Sobes Copilot
Получайте ответы в реальном времени
Ответ от нейросети
sobes.tech AI
В Golang дедлок чаще всего возникает при работе с мьютексами и каналами.
Возможные случаи:
-
Циклическая зависимость мьютексов: Две или более горутины пытаются получить блокировку на мьютексы в разном порядке, создавая взаимоблокировку.
// goroutine 1 mu1.Lock() mu2.Lock() // ждет mu2, который занят goroutine 2// goroutine 2 mu2.Lock() mu1.Lock() // ждет mu1, который занят goroutine 1 -
Блокирующая отправка в небуферизованный канал, который никто не читает: Горутина отправляет данные в канал, но нет другой горутины, готовой их принять.
ch := make(chan int) ch <- 1 // блокируется навсегда, если нет получателя -
Блокирующее чтение из канала, в который никто не пишет: Горутина пытается прочитать данные из канала, но никто не отправляет в него данные.
ch := make(chan int) <-ch // блокируется навсегда, если нет отправителя -
Использование одного и того же мьютекса в рекурсивной функции без
RWMutex:var mu sync.Mutex func recursiveFunc() { mu.Lock() // попытка повторно заблокировать тот же мьютекс // ... // mu.Unlock() // никогда не будет достигнуто } -
Отправка в закрытый канал или чтение из закрытого канала без проверки: Отправка в закрытый канал вызовет панику, чтение из закрытого канала вернет нулевое значение и
false, но если не проверять второй возвращаемый параметр, можно некорректно обработать ситуацию и потенциально привести к дедлоку в другом месте. -
Неправильное использование
sync.WaitGroup: Например, вызовDone()раньше, чем было выполнено необходимое количествоAdd(), или вызовWait()раньше, чем все горутины завершили свою работу.
Таблица с примерами:
| Ситуация | Механизм | Пример |
|---|---|---|
| Циклическая зависимость мьютексов | sync.Mutex |
Горутина A ждет B, Горутина B ждет A |
| Блокирующая отправка в канал | Небуферизованный канал | ch <- data без получателя |
| Блокирующее чтение из канала | Канал | <-ch без отправителя |
| Рекурсивное использование мьютекса | sync.Mutex |
Повторная блокировка в той же горутине |
| Работа с закрытым каналом без проверки | Канал | Отправка в закрытый канал |
Неправильное использование WaitGroup |
sync.WaitGroup |
Ошибки в логике Add/Done/Wait |