Ответ
Горутина прекращает свое выполнение в следующих основных случаях:
Естественное завершение: Функция, запущенная в горутине, выполнила все свои инструкции и дошла до конца.
Явный вызов
runtime.Goexit()
: Эта функция немедленно прекращает выполнение текущей горутины. При этом все отложенные вызовы (defer
) будут выполнены.Неперехваченная паника (
panic
): Если в горутине происходит паника, и она не обрабатывается с помощьюrecover
, выполнение горутины прекращается. Это также приведет к завершению всей программы, если паника не будет обработана на более высоком уровне.Завершение программы: Когда
main
функция завершает свою работу, программа завершается, и все еще работающие горутины принудительно останавливаются без выполненияdefer
.Отмена через контекст (
context
): В современном Go это предпочтительный способ для контролируемого завершения горутин. Горутина периодически проверяет состояние контекста, и если он был отменен (например, по тайм-ауту или по сигналу из другой горутины), она должна корректно завершить свою работу.
// Пример ожидания завершения горутины с помощью WaitGroup
var wg sync.WaitGroup
wg.Add(1) // Увеличиваем счетчик горутин
go func() {
defer wg.Done() // Уменьшаем счетчик по завершении
fmt.Println("Горутина работает...")
time.Sleep(1 * time.Second)
fmt.Println("Горутина завершает работу.")
}()
fmt.Println("main: Ожидание завершения горутины...")
wg.Wait() // Блокируемся, пока счетчик не станет равен 0
fmt.Println("main: Горутина завершилась, программа продолжается.")