В чем разница goroutine и потока операционной системы
Что проверяют
Понимаете ли вы, что горутина это не поток, и знаете ли, как рантайм раскладывает их по потокам. Заодно проверяют, за счёт чего Go держит сотни тысяч одновременных задач.
Как отвечать
Поток операционной системы создаёт ядро: стек в несколько мегабайт, дорогое создание, переключение контекста через ядро. Горутина создаётся рантаймом Go: стек начинается с пары килобайт и растёт по мере надобности, создание стоит наносекунды, переключение происходит в пространстве пользователя.
Дальше опишите модель планирования, ради этого вопрос и задают:
- рантайм раскладывает множество горутин по небольшому числу потоков, число которых по умолчанию равно числу ядер (
GOMAXPROCS); - в модели три сущности: горутина, поток и логический процессор с локальной очередью готовых горутин. Свободный процессор забирает работу у соседа, чтобы никто не простаивал;
- планировщик кооперативный с вытеснением: переключение происходит на блокирующих операциях, обращениях к каналам, вызовах рантайма, а с версии 1.14 и по сигналу, что горутина работает слишком долго;
- если горутина уходит в блокирующий системный вызов, рантайм отцепляет её поток и отдаёт логический процессор другим, поэтому одна операция с диском не останавливает остальные.
Практический вывод: горутины дёшевы, но не бесплатны. У каждой должен быть владелец и способ завершиться, иначе получается утечка горутин, которая видна как растущее число в профиле goroutine.
Где спотыкаются
Считают, что каждая горутина это отдельный поток, и боятся запускать их тысячами.
Приравнивают GOMAXPROCS к числу горутин. Это ограничение параллелизма, а не количества задач.
Забывают, что вызов C-кода через cgo занимает поток целиком и ломает эту экономику.