Как ответить
Горутина — это легковесный поток выполнения в Go, который работает поверх системных потоков ОС. Её запускают ключевым словом go перед вызовом функции. Главное отличие от потоков ОС — горутины дешевле: стек стартует с 2–4 КБ и растёт по мере необходимости, а переключение между ними обходится в десятки наносекунд, а не микросекунды, как у потоков.
Внутри горутины выполняются на пуле системных потоков (обычно GOMAXPROCS, по умолчанию равен числу ядер). Планировщик Go (GMP-модель) распределяет горутины по потокам: когда горутина блокируется на системном вызове или канале, планировщик вытесняет её и запускает другую на том же потоке. Это позволяет эффективно использовать ядра без ручного управления тредами.
Пример:
package main
import (
"fmt"
"time"
)
func printNumbers() {
for i := 1; i <= 5; i++ {
time.Sleep(100 * time.Millisecond)
fmt.Println(i)
}
}
func main() {
go printNumbers()
time.Sleep(600 * time.Millisecond)
fmt.Println("main done")
}Здесь printNumbers запускается как горутина и выполняется параллельно с main. Без time.Sleep main завершится раньше, и горутина не успеет выполниться — программа завершится, не дождавшись её.
Важно: горутины не имеют идентификаторов, их нельзя убить извне — только через каналы или контекст. Ошибка в горутине (паника) уронит всю программу, если не использовать recover внутри неё.
Синхронизация между горутинами — через каналы (chan) или примитивы из пакета sync (WaitGroup, Mutex). Каналы — основной способ: они типизированы и блокируют отправителя/получателя до готовности другой стороны.