Горутина — это легковесный поток выполнения, управляемый Go runtime (не ОС). Запускается через go f(). Стартовый стек ~2-4 КБ (против ~1 МБ у OS-потока), поэтому можно спокойно запускать тысячи и даже миллионы горутин.
go func() {
fmt.Println("работаю в горутине")
}()
Go scheduler мультиплексирует горутины на OS-потоки (M:N scheduling). Горутины кооперативно уступают управление в точках: вызовы функций, channel-операции, системные вызовы.
Важно: main() — тоже горутина. Если main завершится, все остальные горутины убиваются без cleanup. Для ожидания используй sync.WaitGroup или каналы.