Цикл статей "собеседование на понимание" направлен на объяснение простыми словами различных тем. Сегодняшний вопрос на собеседовании backend python: "Расскажите чем отличается поток, процесс, зеленый поток, для чего нужен GIL"
Определения
Выполнение приложения процессором - выполнение инструкций байт кода приложения.
Процесс - выделенная область памяти для выполнения приложения. Запуская приложения мы порождаем процесс. У процесса есть множество свойств и своя структура для управления выполнением приложения.
Поток - часть процесса в которой выполняется приложение. Поток это сущность операционной системы, которая управляется ОС. В языках программирования можно создать и запустить потоки. Но обслуживать их будет ОС. Несколько потоков на одном ядре, работают конкурентно, планировщик их опрашивает и переключает между собой до выполнения. НО при ожидания, например ответа от сети (ввода вывода), другой поток может работать в это время-получается как бы параллельная работа(пока мы ожидаем ответ от сети, ядро может работать, или запустить ещё один запрос в сеть)
Ядро - независимая единица процессора, которая может обслуживать только один поток приложения(два одновременно не может).
Зелёный поток(сопрограмма) - здесь слово поток может путать, т.к. это не поток ОС, а подпрограмма(функция) которая может передать управление другой подпрограмме в момент блокировки ввода вывода. Работают в одном потоке ОС и построены так чтобы использовать время ожидания ввода вывода(сеть, БД, файлы) для выполнения других задач. По сути зелёные потоки работают также как потоки ОС на одном ядре. Если операция процессорная, то профита по времени выполнения не будет. Здесь термин зеленый поток применяется в контексте асинхронности, подходов к реализации которой много(самые популярные: asyncio, gevent).
GIL - блокировщик интерпретатора python. Он блокирует обращение к интерпретатору(процессу cpython который выполняет байт код приложения) из разных потоков ОС. Это простое решение чтобы избежать конфликтов при многопоточности, связано с подсчётом ссылок на объекты приложения. Это историческая особенность интерпретатора cpython.
Примеры комбинаций потоков и ядер
п. | комбинация | java, c# | cpyton |
1 | Один поток, одно ядро | Последовательное выполнение инструкций | Также |
2 | Два потока, одно ядро | Последовательное(конкурентное) выполнение процессорных операций, и параллельное выполнение операций ввода вывода. | Также |
3 | Два потока, два ядра | Параллельное выполнение всех задач с учетом конкуренции потоков за ресурсы. | Второе ядро не будет обслуживать поток ОС, т. к. включится GIL и инструкции будут выполняться как в п. 2 |
4 | Один поток ОС, 1000 зелёных потоков | Параллельное выполнение операций ввода вывода. Теоретически можно использовать обычные потоки, но есть отличия в пользу зелёных, об отличиях ниже. | Также Лучшая практика в python |
Сравнение зеленых потоков и потоков ОС
Потоки ОС: ресурсоемкие, дольше переключаются, не детерминированы, упреждающее управление(момент переключения определяет планировщик ОС)
Зелёные потоки: лёгкие, детерминированные, кооперативное управление(поток сам передаёт управление другому потоку), контролируемое создание и управление, работают в одном потоке ОС
Вывод
В python работа с потоками ограничена GIL. Использовать потоки допустимо, но профит будет только для bound I/O задач. С учетом того что потоки ОС тяжелей зеленых потоков рациональней использовать последние. Для ускорения процессорных задач в python есть multiprocessing.