Back to questions
Junior — Middle
86
Что такое взаимная блокировка (Deadlock) при использовании горутин и как ее избежать?
Answer from AI
sobes.tech AI
Взаимная блокировка (deadlock) в контексте горутин — это ситуация, когда две или более горутины навсегда блокируют друг друга, ожидая освобождения ресурсов, которые заняты друг другом. Например, если горутина A ждёт ресурс, занятый горутиной B, а горутина B ждёт ресурс, занятый горутиной A, то возникает взаимная блокировка.
В Go это может проявляться при неправильном использовании каналов или мьютексов. Например, если горутина пытается отправить данные в канал, но никто не читает из него, или если несколько горутин пытаются захватить мьютексы в разном порядке.
Как избежать взаимной блокировки:
- Избегайте циклических зависимостей при захвате нескольких мьютексов — всегда захватывайте их в одном и том же порядке.
- Используйте буферизированные каналы, чтобы избежать блокировки при отправке, если это уместно.
- Применяйте таймауты и контексты (context.Context) для отмены операций, если ожидание затягивается.
- Минимизируйте количество блокирующих операций и старайтесь проектировать архитектуру так, чтобы горутины не зависели друг от друга напрямую.
Пример простой deadlock ситуации с каналами:
ch := make(chan int)
func main() {
go func() {
ch <- 1 // блокируется, т.к. никто не читает
}()
// main не читает из ch, горутина навсегда заблокирована
}
Чтобы избежать, нужно читать из канала:
ch := make(chan int)
func main() {
go func() {
ch <- 1
}()
val := <-ch // чтение разблокирует горутину
fmt.Println(val)
}