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

В чем разница между параллельностью и конкурентностью?

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

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

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

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

Параллельность vs Конкурентность

Эти два термина часто путают, но они означают разные вещи в программировании.

Основное определение

Конкурентность — это программа выполняет множество задач, переключаясь между ними (но не одновременно).

Параллельность — это программа выполняет множество задач одновременно (на разных ядрах процессора).

Визуальная аналогия

Конкурентность (Concurrency):
Человек ест суп, потом пьёт чай, потом кусает хлеб.
Он может быстро переключаться между действиями, но в момент времени делает одно.

┌──────┐
│ Суп  │ ┌──────┐
└──────┘ │ Чай  │ ┌────────┐
         └──────┘ │ Хлеб   │
                  └────────┘

Параллельность (Parallelism):
Три человека одновременно едят суп, пьют чай и едят хлеб.
Они работают в один момент времени.

┌──────┬──────┬────────┐
│ Суп  │ Чай  │ Хлеб   │
└──────┴──────┴────────┘

Практический пример на Python

Конкурентность (asyncio, threading)

import asyncio
import time

async def task(name, seconds):
    print(f"Задача {name} начинается")
    await asyncio.sleep(seconds)  # Имитация работы
    print(f"Задача {name} закончилась")

async def concurrent_example():
    # Обе задачи выполняются конкурентно
    # Когда одна ждёт (await), выполняется другая
    await asyncio.gather(
        task("A", 2),
        task("B", 2)
    )

# Результат: ~2 секунды (они переключаются)
start = time.time()
asyncio.run(concurrent_example())
print(f"Время: {time.time() - start:.1f}s")  # 2.0s

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

import multiprocessing
import time

def task(name, seconds):
    print(f"Задача {name} начинается")
    time.sleep(seconds)  # Реальная блокировка
    print(f"Задача {name} закончилась")

def parallel_example():
    # Обе задачи выполняются параллельно на разных ядрах
    p1 = multiprocessing.Process(target=task, args=("A", 2))
    p2 = multiprocessing.Process(target=task, args=("B", 2))
    
    p1.start()
    p2.start()
    
    p1.join()
    p2.join()

# Результат: ~2 секунды (работают одновременно)
start = time.time()
parallel_example()
print(f"Время: {time.time() - start:.1f}s")  # 2.0s

GIL в Python

Важно знать о Global Interpreter Lock (GIL):

import threading
import time

def cpu_bound_task():
    total = 0
    for i in range(50_000_000):
        total += i
    return total

# НЕПРАВИЛЬНО для CPU-bound задач (из-за GIL)
def bad_approach():
    t1 = threading.Thread(target=cpu_bound_task)
    t2 = threading.Thread(target=cpu_bound_task)
    
    start = time.time()
    t1.start()
    t2.start()
    t1.join()
    t2.join()
    print(f"Потоки: {time.time() - start:.1f}s")  # Не быстрее одного потока!

# ПРАВИЛЬНО для CPU-bound задач
def good_approach():
    p1 = multiprocessing.Process(target=cpu_bound_task)
    p2 = multiprocessing.Process(target=cpu_bound_task)
    
    start = time.time()
    p1.start()
    p2.start()
    p1.join()
    p2.join()
    print(f"Процессы: {time.time() - start:.1f}s")  # Действительно быстрее

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

Threading (конкурентность)

import threading

def fetch_from_api():
    # I/O-bound операция (сеть, файлы)
    response = requests.get("https://api.example.com/data")
    return response.json()

# Эффективно для I/O операций
threads = []
for _ in range(10):
    t = threading.Thread(target=fetch_from_api)
    threads.append(t)
    t.start()

for t in threads:
    t.join()

Asyncio (конкурентность)

import asyncio
import aiohttp

async def fetch_from_api():
    async with aiohttp.ClientSession() as session:
        async with session.get("https://api.example.com/data") as resp:
            return await resp.json()

# Очень эффективно для I/O с меньшим overhead
async def main():
    tasks = [fetch_from_api() for _ in range(10)]
    results = await asyncio.gather(*tasks)

asyncio.run(main())

Multiprocessing (параллельность)

import multiprocessing

def cpu_intensive_task(n):
    # CPU-bound операция
    return sum(i*i for i in range(n))

# Нужна реальная параллельность
with multiprocessing.Pool(4) as pool:
    results = pool.map(cpu_intensive_task, [100_000_000] * 4)

Сравнение

                 Конкурентность    Параллельность
────────────────────────────────────────────────────
Одновременность   Нет              Да
ОДНО ядро         Да               Нет
I/O операции      Отлично          Хорошо
CPU задачи        Плохо            Отлично
Memory overhead   Низкий           Высокий
Оверхед переключ. Небольшой        Большой
Python GIL        Не помешает       Не помешает
Примеры           asyncio, threading multiprocessing

Итог

  • Конкурентность — переключение между задачами (asyncio, threading)
  • Параллельность — одновременное выполнение на разных ядрах (multiprocessing)
  • Для I/O используй asyncio или threading
  • Для CPU используй multiprocessing
  • GIL в Python блокирует потоки от параллельного выполнения CPU кода
В чем разница между параллельностью и конкурентностью? | PrepBro