Горутина — легковесный поток выполнения. Это означает, что она выполняет код независимо от других задач, но при этом создается и управляется не операционной системой, а самим рантаймом Go. В отличие от классического потока ОС, горутина не требует выделения большого объема памяти для стека и не зависит напрямую от системного планировщика.
Чтобы понять разницу, представьте автомагистраль. Потоки О С — это большие грузовики: они мощные, самостоятельные, но занимают много места и требуют сложной логистики. Горутины — это компактные электросамокаты. Их можно запустить тысячи, они быстро маневрируют, а управляет их движением единая система координации.
Главное отличие заключается в том, как происходит переключение между задачами — так называемый context switching. Когда операционная система переключается между потоками, ей нужно сохранить состояние одного потока, перейти в режим ядра (kernel mode), восстановить состояние другого потока и только после этого продолжить выполнение. Это относительно медленная операция, особенно если потоков много. Чем чаще происходят такие переключения, тем больше накладных расходов. В Go всё устроено иначе. Планировщик горутин работает в user-space, то есть в пространстве пользователя. Переключение между горутинами не требует постоянных переходов в ядро. Рантайм Go сам управляет тем, какие горутины выполняются на каких потоках ОС, и делает это значительно дешевле. Такой легковесный context switching позволяет запускать десятки и сотни тысяч конкурентных задач без серьезной деградации производительности.
Второе важное отличие — размер стека. Поток операционной системы обычно стартует со стеком размером от 1 до 8 мегабайт. Даже если поток почти ничего не делает, память уже зарезервирована. Если создать 10 000 потоков, объём потребляемой памяти будет большим. Горутина стартует с 2 килобайтами стека. Более того, стек динамически растёт и уменьшается по мере необходимости. Это делает горутины крайне эффективными с точки зрения памяти. Благодаря этому Go идеально подходит для сервисов, которые обрабатывают тысячи одновременных соединений — например, веб-серверов или прокси серверов.
На практике это выглядит так: если вы пишете HTTP-сервер на Go, каждый входящий запрос обрабатывается в отдельной горутине. При этом не создаётся полноценный поток ОС под каждый запрос. Вместо этого рантайм распределяет множество горутин по небольшому количеству потоков ОС и эффективно балансирует нагрузку между ядрами. Важно понимать, что горутины — это не «магический параллелизм». Это прежде всего способ организовать конкурентное выполнение задач. Если у машины одно ядро, гоуртины будут выполняться по очереди, быстро переключаясь между собой. Если ядер несколько, Go может выполнять их параллельно.
Именно сочетание трех факторов делает горутины особенными: маленький стартовый стек, дешевое переключение без постоянных переходов в kernel mode и собственный планировщик в user-space. В результате Go позволяет строить масштабируемые системы с высокой производительностью без сложной ручной работы с потоками ОС. Поэтому, когда говорят, что горутины — это легковесные потоки выполнения, имеют в виду не просто «быстро запускаются», а архитектурное отличие: они дешевле по памяти, дешевле по переключению контекста и лучше масштабируются. Это одна из ключевых причин, почему concurrency в Go считается одной из самых удобных и эффективных моделей в современной разработке.