Ответ
Горутина может зависнуть по нескольким причинам:
- Deadlock - когда все горутины ожидают друг друга (например, взаимная блокировка мьютексов)
var mu1, mu2 sync.Mutex
go func() {
mu1.Lock()
mu2.Lock() // зависнет, если другая горутина взяла mu2
}()
go func() {
mu2.Lock()
mu1.Lock() // зависнет, если первая горутина взяла mu1
}()
- Отсутствие выхода - бесконечный цикл без условий завершения
go func() {
for { // вечный цикл
}
}()
- Забытый канал - горутина заблокирована на чтении/записи в канал, который никто не закроет
ch := make(chan int)
go func() {
<-ch // зависнет навсегда
}()
- Голодание - когда горутина не получает ресурсов CPU из-за других горутин
Для диагностики можно использовать pprof или runtime.Stack().