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

Что такое параллельность?

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

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

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

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

Параллельность (Concurrency) в программировании

Параллельность — это свойство системы выполнять несколько задач так, чтобы они казались выполняющимися одновременно. Это не то же самое, что параллелизм (parallelism): параллельность логическая, параллелизм физический.

Основное различие: параллельность vs параллелизм

Параллелизм (Parallelism):

  • Несколько процессов одновременно выполняются на разных ядрах процессора
  • Истинное одновременное выполнение
  • На многоядерном компьютере

Параллельность (Concurrency):

  • Несколько задач чередуются (переключаются контекст) на одном ядре
  • Кажется, что выполняются одновременно, но на самом деле по очереди
  • На одноядерном компьютере можно иметь параллельность, но не параллелизм
// Параллелизм (2 ядра):
Ядро 1: [Task A] [Task A] [Task A]
Ядро 2: [Task B] [Task B] [Task B]
         ↑ выполняются одновременно

// Параллельность (1 ядро):
Ядро 1: [Task A] [Task B] [Task A] [Task B]
         ↑ чередуются, но один процессор

В Python: три подхода к параллельности

1. Threading — многопоточность

Несколько потоков в одном процессе, но из-за GIL (Global Interpreter Lock) только один выполняется в момент времени. Идеален для I/O-bound задач.

import threading
import requests

def fetch_url(url):
    response = requests.get(url)
    print(f"Fetched {url}: {response.status_code}")

urls = ["https://api1.com", "https://api2.com", "https://api3.com"]

# Создаём потоки
threads = []
for url in urls:
    thread = threading.Thread(target=fetch_url, args=(url,))
    threads.append(thread)
    thread.start()

# Ждём завершения всех потоков
for thread in threads:
    thread.join()

print("All requests completed")

Плюсы:

  • Простой синтаксис
  • Разделяют память процесса

Минусы:

  • GIL не позволяет истинному параллелизму CPU-bound операций
  • Race conditions при доступе к общим данным

2. Asyncio — асинхронность

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

import asyncio
import aiohttp

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

async def main():
    urls = ["https://api1.com", "https://api2.com", "https://api3.com"]
    
    async with aiohttp.ClientSession() as session:
        # Запускаем все запросы параллельно
        tasks = [fetch_url(session, url) for url in urls]
        results = await asyncio.gather(*tasks)
    
    return results

results = asyncio.run(main())
print(results)

Плюсы:

  • Легче, чем threading, нет overhead на переключение потоков
  • Предсказуемое переключение контекста (в await точках)
  • Лучше масштабируется на десятки тысяч одновременных операций

Минусы:

  • Требует async/await синтаксис
  • Не подходит для CPU-bound задач

3. Multiprocessing — мультипроцессинг

Несколько отдельных процессов, каждый со своим Python интерпретатором и памятью. Игнорирует GIL, истинный параллелизм.

from multiprocessing import Pool
import hashlib

def compute_hash(data):
    """CPU-bound задача"""
    return hashlib.sha256(data.encode()).hexdigest()

if __name__ == "__main__":
    data = [f"data_{i}" for i in range(10)]
    
    # Используем 4 процесса
    with Pool(4) as pool:
        results = pool.map(compute_hash, data)
    
    print(results)

Плюсы:

  • Истинный параллелизм на многоядерных ПК
  • Работает для CPU-bound операций
  • Изолированы друг от друга

Минусы:

  • Overhead на создание процессов
  • Сложнее обмениваться данными между процессами
  • Требует сериализации (pickle) для передачи данных

Сравнение визуально

# Одна задача - 3 URL, каждый 1 сек

# Последовательно (Sequential)
Время: 3 секунды
[URL1] [URL2] [URL3]

# Threading / asyncio (I/O-bound)
Время: 1 сек (все параллельно)
[URL1, URL2, URL3]

# Multiprocessing (CPU-bound)
На 4-ядерном ПК - 1 сек, на 2-ядерном - 2 сек

Когда что использовать

СлучайВыбор
I/O-bound (HTTP, БД, файлы)asyncio (лучше) или threading
CPU-bound (вычисления, обработка)multiprocessing
Простая параллельность без async/awaitthreading
Тысячи одновременных соединенийasyncio
Обработка больших данных на нескольких ядрахmultiprocessing

Итог

Параллельность в Python достигается тремя способами: threading (на одном ядре с GIL), asyncio (асинхронное переключение контекста), multiprocessing (истинный параллелизм через отдельные процессы). Выбор зависит от природы задач: I/O-bound → asyncio, CPU-bound → multiprocessing, смешанное → комбинация подходов.