Asyncio — это библиотека Python для написания конкурентного (concurrent) кода с использованием синтаксиса async/await. В отличие от многопоточности, asyncio использует однопоточную модель с кооперативной многозадачностью (cooperative multitasking).
Сердце asyncio — это цикл событий, который:
import asyncio
async def main():
print('Hello')
await asyncio.sleep(1)
print('World')
asyncio.run(main()) # Запускает event loop
Функции, объявленные через async def
, которые могут приостанавливать выполнение через await
:
async def fetch_data():
print('Fetching data...')
await asyncio.sleep(2) # Неблокирующая задержка
return {'data': 123}
Обертки вокруг корутин, которые планируют их выполнение в event loop:
async def main():
task = asyncio.create_task(fetch_data())
print('Doing other work...')
data = await task
print(data)
Три типа объектов можно использовать с await
:
async def
функции)asyncio.Task
)asyncio.Future
)# Запуск нескольких задач параллельно
async def main():
task1 = asyncio.create_task(operation1())
task2 = asyncio.create_task(operation2())
await asyncio.gather(task1, task2)
Asyncio предоставляет примитивы для синхронизации:
async def worker(lock, id):
async with lock: # Асинхронный контекстный менеджер
print(f'Worker {id} acquired lock')
await asyncio.sleep(1)
import aiohttp
async def fetch_url(url):
async with aiohttp.ClientSession() as session:
async with session.get(url) as response:
return await response.text()
async def get_user(db, user_id):
await db.connect()
user = await db.fetch('SELECT * FROM users WHERE id = $1', user_id)
return user
Корутины построены на генераторах. Ключевое слово await
аналогично yield from
в генераторах.
Asyncio использует колбэки, но скрывает их за синтаксисом async/await.
Использует системные вызовы select/epoll/kqueue для эффективного ожидания I/O.
Asyncio идеально подходит для:
Пример с подсветкой (VSCode style):
import asyncio
from typing import List
async def process_item(item: str) -> str:
await asyncio.sleep(0.1) # Имитация I/O операции
return item.upper()
async def process_all(items: List[str]) -> List[str]:
tasks = [process_item(item) for item in items]
return await asyncio.gather(*tasks)
async def main():
results = await process_all(['a', 'b', 'c'])
print(results) # ['A', 'B', 'C']
asyncio.run(main())