Корутины, зелёные потоки и мультипроцессинг
Корутины и зелёные потоки в Python — это разные концепции, хотя обе используются для параллелизма. Корутины — это "ручной" асинхронизм, зелёные потоки — "автоматический" параллелизм в одном потоке. Но мультипроцессинг все равно круче.
Скажем сразу, что для CPU-задач ни то, ни другое не даст ускорения. Они хороши для I/O-задач.
Корутины (Coroutines)
Что это: Асинхронные функции, работающие в рамках одного потока (thread). Управляются через asyncio в Python.
Как работают: Выполнение приостанавливается на await, позволяя другим корутинам работать в это время. Это кооперативная многозадачность (вы сами указываете, где ждать).
Плюсы: Легковесные, нет затрат на переключение потоков, идеальны для I/O-операций (например, сеть, файлы).
Минусы: Требуют явного управления (await), не параллельны для CPU-задач, так как работают в одном потоке.
Пример: async def process_line() с await asyncio.sleep().
Зелёные потоки (Green Threads)
Что это: Легковесные "потоки", эмулируемые библиотекой (например, gevent), а не ОС. Работают в одном реальном потоке.
Как работают: Автоматически переключаются при блокирующих операциях (I/O), благодаря патчу стандартных модулей (monkey.patch_all()).
Плюсы: Прозрачность (код выглядит как синхронный), автоматическое переключение, хороши для I/O-задач.
Минусы: Не используют многопроцессорность (один поток), требуют патча для совместимости.
Пример: gevent.spawn(worker) для параллельной обработки.
Главные отличия
Управление: - Корутины: Явное (await), вы сами решаете, где ждать. - Зелёные потоки: Неявное, переключение автоматическое при I/O.
Модель: - Корутины: Кооперативная (вы уступаете управление). - Зелёные потоки: Превентивная (библиотека решает за вас).
Инструменты: - Корутины: Встроены в Python через asyncio. - Зелёные потоки: Требуют внешних библиотек (gevent, eventlet).
Использование: - Корутины: Точный контроль над асинхронностью. - Зелёные потоки: Удобство для кода, похожего на синхронный.
CPU-bound tasks
CPU-задачи - это задачи, которые требуют интенсивных вычислений и нагружают процессор (CPU), а не ждут внешних ресурсов вроде сети или диска.
CPU-задачи — это "мозговой штурм" для процессора, а не ожидание данных.
Примеры:
- Математические вычисления (например, вычисление факториала большого числа).
- Обработка изображений (фильтры, рендеринг).
- Сжатие данных или шифрование.
- Поиск в массиве или сложные алгоритмы (например, сортировка).
Особенности:
Основное время тратится на работу процессора, а не на ожидание I/O (ввод/вывод).
В Python такие задачи ограничены GIL (Global Interpreter Lock), из-за чего многопоточность (threads) не ускоряет их на нескольких ядрах.
Чем отличаются от I/O-задач?
I/O-задачи (I/O-bound): Ждут внешних операций (чтение файла, запрос к серверу). Хорошо работают с корутинами и зелёными потоками.
CPU-задачи: "Гоняют" процессор. Для ускорения нужен multiprocessing (несколько процессов) или распараллеливание на ядра.
Multiprocessing
Мультипроцессинг - это подход в программировании, когда для выполнения задач создаются несколько отдельных процессов, каждый из которых работает на своём ядре процессора. В Python это модуль multiprocessing
, который позволяет обойти ограничение GIL (Global Interpreter Lock) и использовать многопроцессорность.
Multiprocessing — это "армия клонов" Python, где каждый делает свою работу на отдельном ядре
Как работает:
Каждый процесс — это независимая копия программы с собственным интерпретатором Python и памятью.
Процессы распределяются по ядрам CPU, что даёт настоящее параллельное выполнение.
Управление через модуль multiprocessing
: создание процессов, пулы (pools), обмен данными через очереди или pipes.
Отличия от потоков/корутин:
- Процессы: - Независимы, используют разные ядра. - Больше памяти и времени на запуск. - Подходят для CPU-задач.
- Потоки (threading): - Делят память, работают в одном процессе. - Ограничены GIL в Python — не параллельны для CPU. - Хороши для I/O-задач.
- Корутины: - В одном потоке, кооперативные. - Легковесные, для I/O.
Когда использовать:
Multiprocessing — для CPU-задач (вычисления, обработка данных), где нужна настоящая многопроцессорность.
Пример: обработка больших массивов чисел, параллельные тяжёлые вычисления.