Что происходит в ядре операционной системы при создании треда
Что проверяют
Различаете ли вы поток и процесс на уровне ядра и связываете ли это с тем, почему потоки в Python помогают не везде. Вопрос любят задавать после рассказа про многопоточность в резюме: смотрят, есть ли за словами модель.
Как отвечать
В Linux поток и процесс создаются одним и тем же системным вызовом, разница только в наборе флагов: что именно потомок разделяет с родителем. У потока общие адресное пространство, таблица файловых дескрипторов, обработчики сигналов и рабочий каталог, а своими остаются идентификатор задачи, регистры, стек в пользовательской памяти, отдельный стек внутри ядра, маска сигналов и приоритет.
Ядро заводит собственную структуру задачи на каждый поток, и планировщик оперирует именно потоками, а не процессами. Таблицы страниц при этом не копируются, поэтому создание потока заметно дешевле создания процесса, а переключение между потоками одного процесса не требует смены адресного пространства и не обнуляет кеш трансляции адресов. Бесплатным оно всё равно не является: под стек резервируются мегабайты виртуальной памяти, а планировщику добавляется работа. Отсюда пулы вместо потока на каждый запрос. Обычный мьютекс в ядро вообще не заходит, пока за блокировку никто не борется.
Дальше про Python: модуль threading создаёт настоящие потоки операционной системы, но глобальная блокировка интерпретатора пускает в байт-код одного за раз. Она отпускается на операциях ввода-вывода и внутри части вычислительных библиотек, поэтому потоки выигрывают на ожидании, а на счёте нужны процессы или расширение на C.
Где спотыкаются
Говорят, что в Python потоки ненастоящие или зелёные. Они самые обычные, их видит планировщик и показывает системный монитор, ограничение накладывает интерпретатор, а не ядро.
Второе: называют pthread_create системным вызовом. Это функция библиотеки: она выделяет стек и структуры пользовательского уровня, а в ядро уходит уже вызов создания задачи с набором флагов общего доступа.
Третье: смешивают потоки с корутинами. Асинхронный код живёт в одном потоке и переключается только в точках ожидания, поэтому он не спасает от тяжёлых вычислений, а глобальная блокировка к нему отношения не имеет вовсе.