Терминология многопоточности: Kernel-level vs User-level, Green Threads, Coroutines, Fibers

Я понимаю, что такое процесс и поток (классический - режима ядра) в чем разница между ними. Но в чем разница между потоками режима ядра и потоками режима пользователя?

Только в том, что в первом случае ос управляет потоками, а во втором случае программа? У каждого из этих типов потоков есть свой стек и регистры, включая счетчик команд и tcb? Как программа может управлять потоками, ведь ос назначает поток на ядро процессора для выполнения. Как будто здесь есть недосказанность и это не потоки в привычном понимании.

Библиотека threading python создает потоки режима ядра?

Потоки режима пользователя это тоже самое что и green thread?

Корутины это сопрограммы и являются ли они green thread? Как создать green thread в python (если это корутины то async/await, еще слышал про библиотеку grenlet)?

Еще в англоязычной среде есть термин fiber (волокно?) как я понял это корутина, когда в рамках одного потока могут существовать еще задачи.

Так вот являются ли потоки режима пользователя, корутины, сопрограммы, green thread, fiber синонимами или между ними различия?

Если green thread это корутины, то тогда их нельзя называть потоками. И название не корректное.

Вообще интересует в контексте python, но объяснение в общем, для всех языков, тоже подойдёт. Перечитал много информации и во многих источниках значения терминов расходятся в итоге не понятно, что к чему относится и что чем является.


Ответы (1 шт):

Автор решения: Pavel Mayorov

Действительно, в индустрии наплодили многовато понятий для обозначения одного и того же. Но реально отличающихся концепций не так уж и много.

Поток режима ядра, или просто "поток", а также "нить" (thread) - это единица планирования системного планировщика. Это объект, про который знает ядро ОС, и который управляется ядром ОС.

Поток режима пользователя, он же "волокно" (fiber), оно же "greenthread", он же "goroutine" - это объект, подобный потоку, имеющий свой стек, регистры и счётчик команд, но про который ОС не знает. Как это работает? Одновременно и просто и сложно. Простая часть заключается в том, что пока волокно не выполняет никаких блокирующих вызовов и не занимает процессор надолго, всё просто работает. Стек волокна - это всего лишь выделенная в куче область памяти, но ядру не важно куда указывает регистр SP.. Сложная часть заключается в том, чтобы найти неблокирующую альтернативу для каждого блокирующего вызова.

Многопоточное планирование волокон часто называется двухуровневым, или же N:M планированием, потому что сначала ядерный планировщик распределяет потоки по ядрам, а потом планировщик пользовательского режима распределяет волокна по потокам.

Безстековые сопрограммы (stackless coroutines), или просто сопрограммы (coroutine), они же корутины - это нечто вроде подпрограмм, но с возможностью множественных возвратов значений с последующим продолжением работы. Сопрограммы не обязательно выступают как элемент обеспечения конкурентности, довольно часто они используются просто для представления последовательностей элементов (такие сопрограммы называются генераторами). Однако, сопрограммы могут выступать и как замена для волокон, обычно совместно с синтаксисом async/await. Важным отличием сопрограммы от волокна является то, что у сопрограммы нет своего собственного стека, только 1 кадр, соответственно, сопрограмма не может переключиться когда передала управление в подпрограмму.

Наконец, стековые сопрограммы (stackfull coroutines) - это гибрид волокон и сопрограмм. Обычно этот термин означает то же самое, что и "волокно". Однако, такие сопрограммы способны возвращать значения, чего волокна делать не умеют.

→ Ссылка