В чем разница горутин в Go и потоков операционной системы
Что проверяют
Понимаете ли вы, как устроен рантайм Go, а не только лозунг «горутины лёгкие». Следом обычно спрашивают про планировщик: что такое G, M и P и что происходит, когда горутина блокируется на системном вызове.
Как отвечать
Начните с того, кто чем управляет. Поток ОС планирует ядро, горутину планирует рантайм Go поверх небольшого пула потоков. Отсюда все различия:
- стек: у горутины он стартует с 2 КБ и растёт по мере нужды, у потока ОС стек фиксированный, на Linux по умолчанию обычно 8 МБ виртуальной памяти;
- переключение: смена горутины происходит в пространстве пользователя и в разы дешевле переключения потоков, которому нужен переход в ядро;
- модель M:N:
Gэто горутина,Mпоток ОС,Pлогический процессор с локальной очередью. ЧислоPзадаётGOMAXPROCS, по умолчанию оно равно числу доступных ядер, а начиная с Go 1.25 на Linux учитывает и CPU-лимит контейнера; - блокировки: сетевой ввод-вывод уходит в netpoller (epoll, kqueue), и поток не простаивает. На блокирующем syscall рантайм отцепляет
Pи отдаёт его другому потоку; - вытеснение: с Go 1.14 планировщик прерывает горутину асинхронно, тугой цикл без вызовов функций больше не вешает остальных;
- идентичность: у горутины нет публичного ID и приоритета, снаружи её не убить, остановка делается через
context.Contextили канал.
Практический вывод: сотни тысяч горутин на одной машине это норма, столько потоков ОС система не потянет. При этом горутины выполняются параллельно на всех ядрах, так что для вычислений они тоже подходят. Если коду нужен конкретный поток (cgo, некоторые GUI-библиотеки), есть runtime.LockOSThread.
Где спотыкаются
Говорят, что горутины крутятся в одном потоке и параллелизма в Go нет. Путают конкурентность с параллелизмом и забывают про GOMAXPROCS.
Считают горутины бесплатными и не думают об утечках: горутина, навсегда повисшая на чтении из канала, держит стек и всё, на что ссылается. Ловят такое через pprof и goleak в тестах.
Повторяют, что потоки ОС «лучше для вычислений». В Go выбора нет: вы всегда пишете горутины, а по потокам их раскладывает рантайм.