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()
, щоб отримати поточний об'єкт
EventLoop
бібліотеки asyncio
.
Потім додаємо в цей EventLoop
корутину hello
і
просимо його її виконати за допомогою методу run_until_complete()
.
На останньому кроці закриваємо EventLoop
з
допомогою методу 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
,
ми розглянемо їх більш детально.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ