Для каких задач наиболее подходит Asyncio
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
asyncio в Python: оптимальные сценарии
asyncio — это встроенная библиотека для асинхронного программирования с использованием async/await. Она идеальна не для всех задач, а для конкретных сценариев, где есть I/O ожидание.
1. Сетевые запросы (HTTP, WebSocket)
Основной use-case: приложение, которое делает много параллельных запросов к другим сервисам.
import asyncio
import aiohttp
async def fetch_multiple_urls():
urls = ["https://api1.com/data", "https://api2.com/data", "https://api3.com/data"]
async with aiohttp.ClientSession() as session:
tasks = [fetch_url(session, url) for url in urls]
results = await asyncio.gather(*tasks)
return results
async def fetch_url(session, url):
async with session.get(url) as resp:
return await resp.json()
# Без asyncio пришлось бы ждать каждый ответ последовательно
# С asyncio пока ждём ответ от API1, обрабатываем API2
2. Работа с БД (async драйверы)
asyncpg для PostgreSQL, motor для MongoDB, aiomysql — позволяют неблокирующие операции с БД.
import asyncpg
async def fetch_users_concurrent():
conn = await asyncpg.connect("postgresql://user:password@localhost/db")
# Параллельные запросы к БД
tasks = [
conn.fetch("SELECT * FROM users WHERE id = $1", user_id)
for user_id in [1, 2, 3, 4, 5]
]
results = await asyncio.gather(*tasks)
await conn.close()
return results
3. WebSocket и real-time приложения
Чат, live-уведомления, multiplayer игры — нужна двусторонняя коммуникация с несколькими клиентами одновременно.
import asyncio
from websockets import serve, WebSocketServerProtocol
connected_clients = set()
async def broadcast(message: str):
for client in connected_clients:
await client.send(message)
async def handler(websocket: WebSocketServerProtocol, path):
connected_clients.add(websocket)
try:
async for message in websocket:
await broadcast(message)
finally:
connected_clients.remove(websocket)
async def main():
async with serve(handler, "localhost", 8000):
await asyncio.Future() # run forever
asyncio.run(main())
4. Асинхронные очереди (Task Queue)
Обработка задач из очереди без блокирования основного потока.
import asyncio
queue = asyncio.Queue()
async def worker(name):
while True:
task = await queue.get()
print(f"Worker {name} is processing {task}")
await asyncio.sleep(1) # имитация работы
queue.task_done()
async def producer():
for i in range(10):
await queue.put(f"task-{i}")
async def main():
# Запуск 3 воркеров
workers = [asyncio.create_task(worker(i)) for i in range(3)]
# Добавление задач
await producer()
# Ожидание выполнения всех задач
await queue.join()
# Остановка воркеров
for w in workers:
w.cancel()
asyncio.run(main())
5. Периодические задачи и планировщик
asyncio позволяет запускать функции через определённые интервалы без отдельного потока.
async def periodic_task():
while True:
print("Running scheduled task...")
# выполняем что-то каждые 5 секунд
await asyncio.sleep(5)
async def main():
# Запускаем периодическую задачу фоном
asyncio.create_task(periodic_task())
# Основная логика приложения
while True:
print("Main app running...")
await asyncio.sleep(1)
asyncio.run(main())
6. API сервер (FastAPI, aiohttp)
Веб-фреймворки на asyncio обрабатывают тысячи одновременных соединений эффективнее, чем синхронные.
from fastapi import FastAPI
import aiohttp
app = FastAPI()
@app.get("/data/{user_id}")
async def get_user_data(user_id: int):
# Параллельные запросы к разным сервисам
async with aiohttp.ClientSession() as session:
user_task = fetch_user_service(session, user_id)
profile_task = fetch_profile_service(session, user_id)
user, profile = await asyncio.gather(user_task, profile_task)
return {"user": user, "profile": profile}
КОГДА НЕ использовать asyncio
- CPU-bound задачи (обработка больших данных, криптография) — используй multiprocessing
- Простой скрипт с 1-2 запросами — избыточная сложность
- Блокирующие операции без async версии — всё равно заблокирует поток (нужен ThreadPoolExecutor)
Итог
asyncio оптимален для I/O-bound приложений с множеством параллельных операций: веб-серверы, микросервисы с внешними API запросами, real-time приложения. Для CPU-bound задач asyncio не поможет из-за GIL.