← Назад к вопросам
В чем разница между асинхронностью и многопоточностью?
2.0 Middle🔥 241 комментариев
#Python Core#Асинхронность и многопоточность
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Разница между асинхронностью и многопоточностью
Асинхронность и многопоточность — это два разных подхода к конкурентному выполнению кода в Python. Хотя оба позволяют выполнять несколько операций параллельно, они работают на принципиально разных уровнях.
Многопоточность (Threading)
Многопоточность использует несколько потоков операционной системы для одновременного выполнения кода:
import threading
import time
def worker(name):
for i in range(3):
print(f"{name}: {i}")
time.sleep(1)
thread1 = threading.Thread(target=worker, args=("Поток-1",))
thread2 = threading.Thread(target=worker, args=("Поток-2",))
thread1.start()
thread2.start()
thread1.join()
thread2.join()
Характеристики:
- Реальный параллелизм на многоядерных системах
- GIL (Global Interpreter Lock) ограничивает параллелизм в CPython
- Синхронизация между потоками требует механизмов блокировки (Lock, Semaphore)
- Поддерживает CPU-bound задачи лучше
- Создание потока — дорогая операция
Асинхронность (Asyncio)
Асинхронность использует один поток и кооперативную многозадачность через event loop:
import asyncio
async def worker(name):
for i in range(3):
print(f"{name}: {i}")
await asyncio.sleep(1)
async def main():
await asyncio.gather(
worker("Таск-1"),
worker("Таск-2")
)
asyncio.run(main())
Характеристики:
- Один поток, но множество задач (coroutines)
- Event loop переключается между задачами при ожидании
- Нет GIL — истинный параллелизм для I/O операций
- Идеален для I/O-bound задач (сеть, файлы)
- Требует явного использования await для операций
- Легче масштабировать тысячи задач
Прямое сравнение
| Аспект | Многопоточность | Асинхронность |
|---|---|---|
| Потоков | Несколько | Один |
| Переключение | Вытесняющее (ОС) | Кооперативное (код) |
| GIL | Ограничивает | Не влияет на I/O |
| CPU-bound | Да | Нет |
| I/O-bound | Да, но медленнее | Да, быстро |
| Сложность | Сложная синхронизация | Проще с await |
| Масштабирование | До десятков потоков | До тысяч задач |
Пример с I/O-bound задачей
# Threading — 10 потоков
import threading
import time
def fetch_data_thread():
time.sleep(2) # Имитация сетевого запроса
return "Данные"
start = time.time()
threads = [threading.Thread(target=fetch_data_thread) for _ in range(10)]
for t in threads:
t.start()
for t in threads:
t.join()
print(f"Threading: {time.time() - start:.2f}s") # ~2 сек
# Asyncio — 10 задач
import asyncio
async def fetch_data_async():
await asyncio.sleep(2)
return "Данные"
async def main():
await asyncio.gather(*[fetch_data_async() for _ in range(10)])
start = time.time()
asyncio.run(main())
print(f"Asyncio: {time.time() - start:.2f}s") # ~2 сек
Когда использовать
Многопоточность:
- CPU-bound задачи (вычисления, обработка)
- Когда нужна простота и нет тысяч операций
- Наследованный код, библиотеки без async поддержки
Асинхронность:
- I/O-bound задачи (сеть, базы данных)
- Нужна высокая масштабируемость
- Web-фреймворки (FastAPI, aiohttp)
- Когда готов работать с async/await