Почему может зависнуть горутина

«Почему может зависнуть горутина» — вопрос из категории Golang, который задают на 23% собеседований Golang Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Горутина может зависнуть по нескольким причинам:

  1. Deadlock - когда все горутины ожидают друг друга (например, взаимная блокировка мьютексов)
var mu1, mu2 sync.Mutex

go func() {
    mu1.Lock()
    mu2.Lock() // зависнет, если другая горутина взяла mu2
}()

go func() {
    mu2.Lock()
    mu1.Lock() // зависнет, если первая горутина взяла mu1
}()
  1. Отсутствие выхода - бесконечный цикл без условий завершения
go func() {
    for { // вечный цикл
    }
}()
  1. Забытый канал - горутина заблокирована на чтении/записи в канал, который никто не закроет
ch := make(chan int)
go func() {
    <-ch // зависнет навсегда
}()
  1. Голодание - когда горутина не получает ресурсов CPU из-за других горутин

Для диагностики можно использовать pprof или runtime.Stack().