Какие знаешь сущности в асинхронности?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Основные сущности в асинхронности Python
Асинхронность в Python реализуется через модуль asyncio и предоставляет целый набор инструментов для параллельного выполнения операций без блокировки потока. Расскажу о главных сущностях.
1. Coroutines (Корутины)
Это функции, определённые с ключевым словом async def, которые могут быть приостановлены и возобновлены:
import asyncio
async def fetch_data(url: str) -> str:
print(f"Fetching {url}...")
await asyncio.sleep(1) # Имитация сетевого запроса
return f"Data from {url}"
# Вызов корутины
result = asyncio.run(fetch_data("https://example.com"))
print(result)
2. Tasks (Задачи)
Таск — это обёртка над корутиной, планирующая её выполнение в event loop. Tasks позволяют одновременно выполнять несколько корутин:
async def main():
# Создание tasks
task1 = asyncio.create_task(fetch_data("url1"))
task2 = asyncio.create_task(fetch_data("url2"))
task3 = asyncio.create_task(fetch_data("url3"))
# Ожидание всех tasks
results = await asyncio.gather(task1, task2, task3)
print(results)
asyncio.run(main())
3. Event Loop (Цикл событий)
Это основной механизм, координирующий выполнение асинхронного кода. Event loop переключается между корутинами, выполняя готовую работу:
import asyncio
async def task(name: str, delay: float):
print(f"{name} started")
await asyncio.sleep(delay)
print(f"{name} completed")
async def main():
# Event loop будет управлять выполнением всех задач
await asyncio.gather(
task("Task1", 2),
task("Task2", 1),
task("Task3", 3)
)
# Явное получение и запуск event loop
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
loop.run_until_complete(main())
4. Futures (Будущие значения)
Future представляет результат, который будет доступен в будущем. Это низкоуровневая абстракция, обычно используется внутренне:
async def example():
# Future часто используется в callbacks
future = asyncio.Future()
def set_result():
future.set_result("Result from callback")
# Запланировать выполнение функции
asyncio.get_event_loop().call_later(1, set_result)
result = await future
print(result)
asyncio.run(example())
5. Callbacks (Обработчики событий)
Функции, выполняющиеся при срабатывании события. Используются в низкоуровневом асинхронном коде:
import asyncio
async def example():
future = asyncio.Future()
def done_callback(future):
print(f"Future done: {future.result()}")
future.add_done_callback(done_callback)
# Установить результат
await asyncio.sleep(1)
future.set_result(42)
asyncio.run(example())
6. Queues (Очереди)
Потокобезопасные очереди для обмена данными между корутинами:
async def producer(queue: asyncio.Queue):
for i in range(5):
await asyncio.sleep(0.5)
await queue.put(f"Item {i}")
print(f"Produced: Item {i}")
async def consumer(queue: asyncio.Queue):
while True:
item = await queue.get()
print(f"Consumed: {item}")
queue.task_done()
async def main():
queue = asyncio.Queue()
await asyncio.gather(
producer(queue),
consumer(queue)
)
asyncio.run(main())
7. Locks и Synchronization Primitives (Примитивы синхронизации)
Инструменты для безопасного доступа к общим ресурсам:
import asyncio
class Counter:
def __init__(self):
self.value = 0
self.lock = asyncio.Lock()
async def increment(self):
async with self.lock:
# Критическая секция
temp = self.value
await asyncio.sleep(0.01) # Имитация работы
self.value = temp + 1
async def main():
counter = Counter()
tasks = [counter.increment() for _ in range(10)]
await asyncio.gather(*tasks)
print(f"Final value: {counter.value}") # 10
asyncio.run(main())
8. Context Managers (Менеджеры контекста)
Асинхронные версии with для управления ресурсами:
import asyncio
class AsyncResource:
async def __aenter__(self):
print("Resource acquired")
return self
async def __aexit__(self, exc_type, exc_val, exc_tb):
print("Resource released")
async def do_something(self):
print("Doing something")
async def main():
async with AsyncResource() as resource:
await resource.do_something()
asyncio.run(main())
9. Streams (Потоки данных)
Для работы с сетевыми соединениями и файлами в асинхронном режиме:
async def handle_client(reader, writer):
data = await reader.read(100)
message = data.decode()
print(f"Received: {message}")
writer.write(b"Response")
await writer.drain()
writer.close()
async def main():
server = await asyncio.start_server(handle_client, "127.0.0.1", 8888)
async with server:
await server.serve_forever()
asyncio.run(main())
Best Practices
- Используй asyncio.gather() для запуска нескольких задач параллельно
- Используй asyncio.wait() для более гибкого контроля над completion
- Избегай блокирующих операций в асинхронном коде (используй библиотеки вроде
aiohttp,asyncpg) - Используй Locks для синхронизации доступа к общим ресурсам
- Обрабатывай исключения в tasks с помощью try/except
Эти сущности составляют основу асинхронного программирования в Python и позволяют эффективно работать с I/O-bound операциями.