5.1 Event Loop
Теперь кратенько коснёмся второй части асинхронности, которая так и лезла со всех сторон: цикл событий Event Loop, таски Task и Future.
Представьте Event Loop как дирижёра оркестра, Task как музыкантов, а Future как ноты, которые музыканты должны сыграть. Дирижёр Event Loop координирует работу музыкантов Task, которые исполняют музыку (асинхронные операции), читая ноты Future.
Цикл событий Event Loop является основой асинхронного программирования в Python. Он отвечает за выполнение асинхронных задач, управление событиями и обработку ввода-вывода. Цикл событий непрерывно проверяет наличие новых событий или задач и запускает их по мере готовности.
Основные функции
-
run_forever(): Запускает цикл событий и продолжает его выполнение до вызоваstop(). -
run_until_complete(future): Запускает цикл событий и завершает его после завершения заданного будущего объекта или корутины. stop(): Останавливает цикл событий.-
create_task(coroutine): Планирует выполнение корутины как задачи.
Пример использования:
import asyncio
async def hello():
print("Hello, world!")
await asyncio.sleep(1)
print("Hello again!")
loop = asyncio.get_event_loop()
loop.run_until_complete(hello())
loop.close()
В этом примере сначала мы используем метод get_event_loop(), чтобы получить текущий объект Event Loop библиотеки asyncio.
Затем добавляем в этот Event Loop корутину hello и просим его её выполнить с помощью метода run_until_complete().
На последнем шаге закрываем Event Loop с помощью метода close().
При выполнении этого кода вы увидите, что сначала выведется "Hello, world!", затем программа подождёт 1 секунду, и после этого выведется "Hello again!". Это демонстрирует, как Event Loop управляет выполнением асинхронной функции.
Подробнее эти действия мы рассмотрим в следующей лекции.
5.2 Tasks
Задачи Tasks представляют собой обёртку для корутин, позволяющую управлять их выполнением и отслеживать их состояние. Задачи позволяют запускать корутины параллельно, управляя ими через цикл событий.
Создание и управление задачами
-
asyncio.create_task(coroutine): Создаёт задачу для выполнения корутины. -
Task.result(): Возвращает результат завершённой задачи или вызывает исключение, если задача завершилась с ошибкой. Task.cancel(): Отменяет выполнение задачи.
Пример использования:
import asyncio
async def say_hello():
await asyncio.sleep(1)
print("Hello")
async def main():
task = asyncio.create_task(say_hello())
await task
asyncio.run(main())
В данном примере мы оборачиваем корутину say_hello() объектом Task. Он тоже является асинхронным объектом, поэтому чтобы получить его результат, нужно применить к нему оператор await.
При выполнении этого кода программа подождёт 1 секунду, а затем выведет "Hello". Это показывает, как Task управляет выполнением корутины и как мы можем ожидать её завершения с помощью await.
Более подробно о работе с задачами Task будет рассказано в следующей лекции.
5.3 Futures
Объекты Future представляют собой результат асинхронной операции, который будет доступен в будущем. Они позволяют управлять состоянием асинхронной операции, устанавливая результат или исключение.
Основные методы:
-
set_result(result): Устанавливает результат для объектаFuture. -
set_exception(exception): Устанавливает исключение для объектаFuture. -
result(): Возвращает результат объектаFutureили вызывает исключение, если операция завершилась с ошибкой. -
exception(): Возвращает исключение, если оно было установлено.
Пример использования:
import asyncio
async def set_future(fut, value):
await asyncio.sleep(1)
fut.set_result(value)
async def main():
loop = asyncio.get_running_loop()
fut = loop.create_future()
await set_future(fut, 'Hello, future!')
print(fut.result())
asyncio.run(main())
В этом примере мы создаём Future, устанавливаем его значение через секунду, а затем выводим результат. Вы увидите, что программа подождёт секунду, прежде чем вывести 'Hello, future!'. Это демонстрирует, как Future представляет результат, который станет доступен в будущем.
В отличие от объекта Task, объект Future привязан к конкретному Event Loop, и выполняемая асинхронная функция может записать в него свой результат. Хотя обычно это работает немного иначе.
Чаще всего объекты Future используются в связке с задачами Task, которые обеспечивают более высокоуровневое управление асинхронными операциями.
Теперь после того, как вы познакомились с Event Loop, Task и Future, мы рассмотрим их более подробно.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ