Какие основные подходы к конкурентному и параллельному выполнению кода есть в Python?

Ответ

В Python существует три основных подхода для организации конкурентного и параллельного выполнения кода, каждый из которых решает свой класс задач.

  1. Многопоточность (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()

  2. Многопроцессорность (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()

  3. Асинхронность (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())

Подход Лучше для... Обход GIL Основная единица
threading I/O-bound Нет Поток
multiprocessing CPU-bound Да Процесс
asyncio I/O-bound (масштабируемое) Нет Задача (Task)