← Назад к вопросам

Есть ли в Python полная поддержка параллелизм?

2.3 Middle🔥 231 комментариев
#Python Core#Асинхронность и многопоточность

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Есть ли в Python полная поддержка параллелизма?

Короткий ответ: Нет, в CPython полной поддержки параллелизма нет из-за GIL. Но есть решения.

Проблема: Global Interpreter Lock (GIL)

GIL — это мьютекс в CPython, который позволяет только одному потоку выполнять Python код одновременно.

import threading
import time

def cpu_intensive(n):
    # Сложные вычисления
    total = 0
    for i in range(n):
        total += i ** 2
    return total

start = time.time()

# ❌ Потоки НЕ распараллелятся на CPU из-за GIL
t1 = threading.Thread(target=cpu_intensive, args=(100_000_000,))
t2 = threading.Thread(target=cpu_intensive, args=(100_000_000,))

t1.start()
t2.start()
t1.join()
t2.join()

print(f"Потоки: {time.time() - start:.2f}с")  # ~10 сек (двойное время!)

# ✅ Процессы распараллелятся идеально
from multiprocessing import Process

start = time.time()

p1 = Process(target=cpu_intensive, args=(100_000_000,))
p2 = Process(target=cpu_intensive, args=(100_000_000,))

p1.start()
p2.start()
p1.join()
p2.join()

print(f"Процессы: {time.time() - start:.2f}с")  # ~5 сек (параллельно!)

Три уровня параллелизма

1. Многопоточность (Threading) — для I/O

Потоки НЕ параллельны для CPU-bound задач, но идеальны для I/O-bound.

import threading
import requests

def fetch_url(url):
    response = requests.get(url)  # БЛОКИРУЕТ, но отпускает GIL
    return response.status_code

start = time.time()

urls = ['http://example.com'] * 10
threads = [threading.Thread(target=fetch_url, args=(url,)) for url in urls]

for t in threads:
    t.start()
for t in threads:
    t.join()

print(f"Многопоточность: {time.time() - start:.2f}с")  # ~1 сек (параллельно!)

Почему работает: Когда поток ждёт сетевого ответа, он отпускает GIL, позволяя другим потокам выполняться.

2. Многопроцессность (Multiprocessing) — для CPU

Процессы — это отдельные Python интерпретаторы, каждый со своим GIL.

from multiprocessing import Pool
import time

def factorial(n):
    result = 1
    for i in range(1, n + 1):
        result *= i
    return result

if __name__ == '__main__':
    start = time.time()
    
    # Использование процессов
    with Pool(processes=4) as pool:
        results = pool.map(factorial, [10000] * 4)
    
    print(f"Многопроцессность: {time.time() - start:.2f}с")  # ~5 сек
    
    # Сравнение: последовательное выполнение
    start = time.time()
    results = [factorial(10000) for _ in range(4)]
    print(f"Последовательно: {time.time() - start:.2f}с")  # ~20 сек

3. Асинхронность (Async) — для высокой конкурентности

Один поток, много корутин. Идеально для тысяч одновременных операций I/O.

import asyncio
import aiohttp

async def fetch_url_async(url):
    async with aiohttp.ClientSession() as session:
        async with session.get(url) as response:
            return response.status

async def main():
    start = time.time()
    
    tasks = [fetch_url_async('http://example.com') for _ in range(100)]
    results = await asyncio.gather(*tasks)
    
    print(f"Асинхронность: {time.time() - start:.2f}с")  # ~1 сек для 100 запросов

if __name__ == '__main__':
    asyncio.run(main())

Сравнительная таблица

ПодходCPU-boundI/O-boundСложностьМасштабируемость
Threading❌ Нет✅ ДаНизкаяСотни
Multiprocessing✅ Да❌ НетСредняяПроцессоры
Async❌ Нет✅ ДаСредняяТысячи

Решения для полного параллелизма

1. PyPy

# PyPy имеет другую реализацию и может быть быстрее
pypy3 your_script.py

2. Jython / IronPython

Другие реализации Python без GIL.

3. Cython для критичного кода

# fast_code.pyx
cpdef int factorial(int n):
    cdef int result = 1
    cdef int i
    for i in range(1, n + 1):
        result *= i
    return result

4. Расширения на C/C++

# Вызов C функций отпускает GIL
import ctypes

libc = ctypes.CDLL('libc.so.6')
result = libc.function()  # Выполняется без GIL

5. Python 3.13+ с экспериментальным режимом без GIL

python3.13 -X gil=0 your_script.py  # Экспериментально!

Практические рекомендации

# ❌ Ошибка: использовать threading для CPU-bound
from threading import Thread
result = sum(n**2 for n in range(100_000_000))  # Медленно!

# ✅ Правильно: использовать multiprocessing
from multiprocessing import Pool
with Pool() as p:
    result = sum(p.map(lambda n: n**2, range(100_000_000)))

# ❌ Ошибка: использовать threading для 10000 одновременных операций
threads = [Thread(target=fetch, args=(url,)) for url in urls]

# ✅ Правильно: использовать async
async def main():
    tasks = [fetch_async(url) for url in urls]
    return await asyncio.gather(*tasks)

Итоговый ответ

Python НЕ имеет полной поддержки параллелизма из-за GIL в CPython, но:

  • I/O-bound: Threading и Async работают отлично
  • CPU-bound: Multiprocessing работает идеально
  • Смешанные задачи: Комбинируй подходы
  • Критичный код: Пиши на C/Cython

GIL — это не проблема, если использовать правильный инструмент для задачи.