Ответ
В Python существует три основных подхода для организации конкурентного и параллельного выполнения кода, каждый из которых решает свой класс задач.
-
Многопоточность (
threading)- Принцип: Несколько потоков выполняются в рамках одного процесса и разделяют общую память.
- Ограничение: Глобальная блокировка интерпретатора (GIL) не позволяет нескольким потокам одновременно выполнять Python-байткод. Из-за этого
threadingне дает прироста производительности на CPU-bound задачах (вычислительных). - Применение: Идеально подходит для I/O-bound задач (ожидание сети, диска, базы данных), так как GIL освобождается на время операций ввода-вывода, позволяя другому потоку выполняться.
import threading
def io_task():
Симуляция сетевого запроса
print("Поток начал работу")thread = threading.Thread(target=io_task) thread.start() thread.join()
-
Многопроцессорность (
multiprocessing)- Принцип: Запускаются отдельные процессы, каждый со своим интерпретатором Python и своим экземпляром GIL. Процессы не разделяют память по умолчанию.
- Преимущество: Позволяет достичь настоящего параллелизма и полностью утилизировать все ядра процессора.
- Применение: Эффективен для CPU-bound задач (математические вычисления, обработка больших объемов данных).
from multiprocessing import Process
def cpu_task():
Симуляция вычислений
sum(i * i for i in range(10**7))process = Process(target=cpu_task) process.start() process.join()
-
Асинхронность (
asyncio)- Принцип: Конкурентное выполнение в одном потоке с помощью событийного цикла (event loop) и корутин (
async/await). - Преимущество: Очень низкие накладные расходы на переключение контекста по сравнению с потоками. Позволяет эффективно обрабатывать тысячи одновременных I/O-операций.
- Применение: Высокопроизводительные I/O-bound задачи, особенно сетевые приложения (веб-серверы, клиенты API, боты).
import asyncio
async def async_io_task():
Асинхронная I/O операция
await asyncio.sleep(1) print("Асинхронная задача завершена")asyncio.run(async_io_task())
- Принцип: Конкурентное выполнение в одном потоке с помощью событийного цикла (event loop) и корутин (
| Подход | Лучше для... | Обход GIL | Основная единица |
|---|---|---|---|
threading |
I/O-bound | Нет | Поток |
multiprocessing |
CPU-bound | Да | Процесс |
asyncio |
I/O-bound (масштабируемое) | Нет | Задача (Task) |