Конкурентность и параллелизм: важная разница
Два слова, которые путают чаще всего: конкурентность и параллелизм — это не одно и то же.
Конкурентность — это способность системы управлять несколькими задачами, которые продвигаются с перекрытием во времени; параллелизм — это физически одновременное выполнение нескольких задач на разных вычислительных ядрах.
Конкурентность — про структуру: вы разбили программу на независимые задачи, и система чередует их, переключаясь между ними. Параллелизм — про выполнение: задачи реально бегут в одну и ту же физическую миллисекунду на разных ядрах процессора.
Аналогия с поваром
Один повар (одно ядро) готовит три блюда. Пока варится суп, он режет салат, потом переключается на жарку — это конкурентность: одна голова, но несколько дел в работе одновременно по смыслу. Если поставить трёх поваров, каждый делает своё блюдо в один и тот же момент — это параллелизм.
Конкурентность (1 ядро, чередование):
Задача A: ## ## ##
Задача B: ## ##
Задача C: ## ##
время ---------------------->
Параллелизм (3 ядра, одновременно):
Ядро 1 A: ##########
Ядро 2 B: ##########
Ядро 3 C: ##########
время ---------------------->Можно одно без другого
Эти свойства независимы. Бывает:
- Конкурентность без параллелизма — одно ядро чередует задачи (классическая однопроцессорная многозадачность, как asyncio).
- Параллелизм без явной конкурентности — например, векторные SIMD-операции над массивом на одном ядре.
- И то и другое — несколько потоков на нескольких ядрах.
Когда что помогает
Параллелизм ускоряет CPU-bound задачи (тяжёлые вычисления) — больше ядер, быстрее счёт. Конкурентность помогает с I/O-bound задачами (сеть, диск): пока один запрос ждёт ответа, можно заняться другим, и ядер для этого много не нужно.
tasks = ["скачать A", "скачать B", "скачать C"]
# моделируем чередование: каждая задача делает шаг по очереди
for step in range(2):
for t in tasks:
print(f"шаг {step}: {t}")Вывод:
шаг 0: скачать A шаг 0: скачать B шаг 0: скачать C шаг 1: скачать A шаг 1: скачать B шаг 1: скачать C
Как работает под капотом
Конкурентность реализуется планировщиком, который чередует задачи: даёт каждой кусочек времени или переключается, когда задача чего-то ждёт. Параллелизм требует физического «железа» — нескольких ядер или процессоров. Поэтому на одноядерной машине вы можете писать конкурентный код, но настоящего параллелизма не получите.
Частые ошибки
- Считать слова синонимами. Можно быть конкурентным без параллелизма и наоборот.
- Ждать ускорения вычислений от конкурентности на одном ядре. Чередование не складывает производительность, оно лишь скрывает ожидание.
- Игнорировать тип нагрузки. Для счёта нужен параллелизм, для ожидания — конкурентность.
Итог
- Конкурентность — про управление многими задачами (структура).
- Параллелизм — про одновременное выполнение (железо).
- I/O-bound выигрывает от конкурентности, CPU-bound — от параллелизма.
- Свойства независимы и могут сочетаться.