Ответ
В Python выбор инструмента для параллелизма зависит от типа задачи. Я использовал следующие подходы:
1. Многопроцессность (multiprocessing) для CPU-bound задач
Идеально для тяжелых вычислений, так как обходит ограничение Global Interpreter Lock (GIL).
from multiprocessing import Pool
def calculate_chunk(data_chunk):
# Интенсивные вычисления (например, обработка изображений)
return [x ** 2 for x in data_chunk]
if __name__ == '__main__':
data = list(range(1000))
with Pool(processes=4) as pool:
# Разделяем данные на части для параллельной обработки
results = pool.map(calculate_chunk, [data[i::4] for i in range(4)])
print(results)
2. Потоки (threading) для I/O-bound задач
Эффективны при множественных операциях ввода-вывода (сеть, диск), где потоки могут ждать, не блокируя друг друга.
import threading
import requests
def fetch_url(url):
response = requests.get(url)
print(f"{url}: {len(response.content)} bytes")
urls = ["https://api.example.com/data1", "https://api.example.com/data2"]
threads = []
for url in urls:
t = threading.Thread(target=fetch_url, args=(url,))
t.start()
threads.append(t)
for t in threads:
t.join()
3. Асинхронное программирование (asyncio) для высокопроизводительных I/O операций
Позволяет управлять тысячами сетевых соединений в одном потоке.
import asyncio
import aiohttp
async def fetch_page(session, url):
async with session.get(url) as response:
return await response.text()
async def main():
async with aiohttp.ClientSession() as session:
tasks = [fetch_page(session, f"https://api.example.com/item/{i}") for i in range(10)]
pages = await asyncio.gather(*tasks)
# Обработка всех полученных страниц
asyncio.run(main())
Ключевой выбор:
multiprocessingдля вычислений (анализ данных, ML).threadingилиconcurrent.futures.ThreadPoolExecutorдля простых операций с файлами или API.asyncioдля написания высоконагруженных сетевых сервисов (веб-скрапинг, микросервисы).