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

Заменял ли мультипроцессинг на асинхронность

1.6 Junior🔥 131 комментариев
#Soft Skills#Асинхронность и многопоточность

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

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

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

Замена мультипроцессинга на асинхронность

Различие в применении

Мультипроцессинг и асинхронность решают разные задачи, хотя обе могут выполнять операции параллельно.

Мультипроцессинг:

  • Для задач, требующих реального параллелизма (CPU-bound)
  • Обходит GIL (Global Interpreter Lock) в Python
  • Использует отдельные процессы с независимыми интерпретаторами
  • Большие накладные расходы на создание процессов

Асинхронность:

  • Для задач с ожиданием (I/O-bound)
  • Выполняется в одном процессе, одном потоке
  • Быстрое переключение между задачами
  • Минимальные накладные расходы

Когда я бы заменил мультипроцессинг на асинхронность

Пример 1: Обработка сетевых запросов

Исходно на мультипроцессинге (неэффективно):

from multiprocessing import Pool
import requests
import time

def fetch_url(url):
    response = requests.get(url, timeout=5)
    return len(response.text)

if __name__ == '__main__':
    urls = ['https://httpbin.org/delay/2'] * 10
    
    start = time.time()
    with Pool(processes=5) as pool:
        results = pool.map(fetch_url, urls)
    print(f"Время (мультипроцессинг): {time.time() - start:.1f} сек")  # ~4 сек

Замена на асинхронность (эффективно):

import asyncio
import aiohttp
import time

async def fetch_url(session, url):
    async with session.get(url, timeout=5) as response:
        return len(await response.text())

async def main():
    urls = ['https://httpbin.org/delay/2'] * 10
    
    start = time.time()
    async with aiohttp.ClientSession() as session:
        tasks = [fetch_url(session, url) for url in urls]
        results = await asyncio.gather(*tasks)
    print(f"Время (асинхронность): {time.time() - start:.1f} сек")  # ~2 сек

asyncio.run(main())

Асинхронность быстрее на 50% и использует меньше памяти.

Пример 2: Парсинг HTML с сохранением в БД

Исходно на мультипроцессинге:

from multiprocessing import Pool
from bs4 import BeautifulSoup
import sqlite3
import requests

def parse_page(url):
    response = requests.get(url)
    soup = BeautifulSoup(response.text, 'html.parser')
    # Проблема: каждый процесс создаёт свое подключение к БД
    conn = sqlite3.connect('data.db')
    cursor = conn.cursor()
    # ... парсинг и сохранение ...
    conn.close()
    return len(soup.find_all('a'))

if __name__ == '__main__':
    urls = ['https://example.com/page1', 'https://example.com/page2']
    with Pool(processes=4) as pool:
        results = pool.map(parse_page, urls)

Замена на асинхронность:

import asyncio
import aiohttp
from bs4 import BeautifulSoup
from sqlalchemy import create_engine
from sqlalchemy.orm import Session

# Одно подключение к БД для всех async задач
engine = create_engine('sqlite:///data.db')

async def parse_page(session, url):
    async with session.get(url) as response:
        text = await response.text()
        soup = BeautifulSoup(text, 'html.parser')
        
        # Используем единый engine для всех задач
        with Session(engine) as db:
            # ... парсинг и сохранение ...
            links_count = len(soup.find_all('a'))
        
        return links_count

async def main():
    urls = ['https://example.com/page1', 'https://example.com/page2']
    async with aiohttp.ClientSession() as session:
        tasks = [parse_page(session, url) for url in urls]
        results = await asyncio.gather(*tasks)

asyncio.run(main())

Преимущества:

  • Одно подключение к БД вместо multiple connections
  • Проще управление ресурсами
  • Лучше производительность

Пример 3: Telegram Bot с асинхронными обработчиками

Вместо использования мультипроцессинга для обработки нескольких пользователей одновременно, используется асинхронность:

from aiogram import Router, F
from aiogram.types import Message
import asyncio

router = Router()

@router.message(F.text == '/start')
async def start_handler(message: Message):
    # Может быть множество пользователей одновременно
    await asyncio.sleep(0.5)  # Имитация I/O операции
    await message.answer("Привет!")

@router.message()
async def any_message_handler(message: Message):
    # Все обработчики выполняются асинхронно
    # Диспетчер singlehandler сам управляет event loop
    await message.answer(f"Вы написали: {message.text}")

Аiogram использует асинхронность для обработки множества пользователей без блокировок.

Когда НЕ заменять мультипроцессинг

Остаются случаи, когда нужен мультипроцессинг:

1. CPU-bound операции:

from multiprocessing import Pool
import math

def compute_prime_count(n):
    """Чистое вычисление — требует реального параллелизма"""
    count = 0
    for i in range(2, n):
        if all(i % j != 0 for j in range(2, int(math.sqrt(i)) + 1)):
            count += 1
    return count

if __name__ == '__main__':
    numbers = [100000, 100000, 100000, 100000]
    with Pool(processes=4) as pool:
        results = pool.map(compute_prime_count, numbers)

2. Обработка больших файлов:

from multiprocessing import Pool

def process_chunk(chunk):
    """Обработка части файла в отдельном процессе"""
    return sum(int(line.strip()) for line in chunk if line.strip())

if __name__ == '__main__':
    # Разделяем большой файл на chunks
    # Обрабатываем параллельно
    with Pool(processes=4) as pool:
        results = pool.map(process_chunk, chunks)

Матрица решений

Тип задачиЛучший выборПочему
I/O операции (сеть, файлы, БД)АсинхронностьБез GIL, быстро, мало памяти
CPU-bound вычисленияМультипроцессингОбходит GIL, настоящий параллелизм
Простые скриптыСинхронный кодПроще, понятнее, достаточно
Веб-приложениеАсинхронность (FastAPI)Сотни одновременных запросов
Обработка данныхЗависит от типаCPU → мультипроцессинг, I/O → асинхронность

Практический совет

В 90% случаев при работе с I/O операциями я заменяю мультипроцессинг на асинхронность. Это дает:

✅ Быстрее (2-5x) ✅ Меньше памяти ✅ Проще отладка ✅ Меньше синхронизации

Мультипроцессинг оставляю только для CPU-bound задач, где нужен настоящий параллелизм.

Заменял ли мультипроцессинг на асинхронность | PrepBro