Ответ
Теоретически, количество горутин в Go не имеет жесткого лимита и ограничено только объемом доступной оперативной памяти (RAM).
Каждая горутина имеет небольшой начальный стек (обычно 2 КБ), который может динамически расти. Это позволяет создавать сотни тысяч и даже миллионы горутин на типичной машине.
На практике количество горутин ограничивается следующими факторами:
- Оперативная память (RAM): Основной ограничитель. Каждая горутина, даже в состоянии ожидания, потребляет память.
- Производительность планировщика Go: При огромном количестве горутин (миллионы) накладные расходы на их планирование могут стать заметными.
- Загрузка CPU: Слишком много активных горутин, конкурирующих за процессорное время, могут привести к частым переключениям контекста и снижению производительности.
- Внешние ресурсы: Количество открытых файловых дескрипторов, сетевых соединений или подключений к базе данных.
Пример запуска 100 000 горутин:
package main
import (
"fmt"
"sync"
"time"
)
func main() {
var wg sync.WaitGroup
for i := 0; i < 100000; i++ {
wg.Add(1)
go func(n int) {
defer wg.Done()
// Имитация полезной работы
time.Sleep(time.Millisecond * 10)
}(i)
}
wg.Wait()
fmt.Println("Все 100 000 горутин завершили работу.")
}
Ключевой вывод: Важно не просто запускать горутины, но и управлять их жизненным циклом, чтобы избегать утечек (когда горутина никогда не завершается) и состояний гонки.