6.1 Отримання циклу подій
Цикл подій (Event Loop)
є центральним компонентом в
асинхронному програмуванні з використанням модуля asyncio в
Python. Він керує виконанням асинхронних задач, обробкою
подій та виконанням операцій введення-виведення. Цикл подій дозволяє
кільком задачам виконуватися одночасно, не блокуючи основний
потік виконання.
Створення і отримання циклу подій
-
asyncio.get_event_loop()
: Повертає поточний цикл подій або створює новий, якщо поточного немає. -
asyncio.new_event_loop()
: Створює новий цикл подій. -
asyncio.set_event_loop(loop)
: Встановлює вказаний цикл подій як поточний.
Приклад:
У asyncio є поточний цикл подій, який містить всі виконувані задачі. Ви можете отримати поточний цикл подій або створити новий і встановити його в якості поточного. Що і відбувається в прикладі нижче.
import asyncio
loop = asyncio.get_event_loop()
print(loop) # Поточний цикл подій
new_loop = asyncio.new_event_loop()
asyncio.set_event_loop(new_loop)
print(asyncio.get_event_loop()) # Новий встановлений цикл подій
Варто зазначити, що метод get_event_loop()
повертає поточний активний цикл подій. Створення нового циклу подій і його встановлення слід використовувати з обережністю, щоб уникнути конфліктів в асинхронних додатках.
Запуск циклу подій
-
run_forever()
: Запускає цикл подій і продовжує його виконання до викликуstop()
. -
run_until_complete(future)
: Запускає цикл подій і завершує його після завершення заданої корутини або майбутнього об'єкта.
Приклад:
Цикл подій можна запустити у двох режимах: працювати нескінченно —
щось типу while True
, або поки не виконається конкретна задача.
import asyncio
async def hello():
print("Hello")
await asyncio.sleep(1)
print("World")
loop = asyncio.get_event_loop()
loop.run_until_complete(hello())
loop.close()
Якщо ви запустили Event Loop
в режимі run_forever()
, він буде крутити
всередині себе цикл нескінченно. Метод run_forever()
закінчить роботу
тільки якщо якась асинхронна задача викличе у нашого EventLoop
метод stop()
.
Зупинка циклу подій
stop()
: Зупиняє цикл подій.-
is_running()
: ПовертаєTrue
, якщо цикл подій запущений.
Приклад:
Якщо цикл запущений в нескінченному режимі, він постійно отримує задачі
і виконує їх, то сам він не зупиниться. Хтось повинен отримати
об'єкт нашого поточного циклу і викликати у нього метод stop()
. Щоб
дізнатися, крутиться вічний цикл чи ні, потрібно викликати метод
is_running()
.
import asyncio
loop = asyncio.get_event_loop()
loop.stop()
print(loop.is_running()) # False
6.2 Важливі методи циклу подій
Метод call_soon(callback, *args)
Планує виклик функції callback
з аргументами *args
якомога
швидше.
import asyncio
def my_callback():
print("Callback executed")
loop = asyncio.get_event_loop()
loop.call_soon(my_callback)
loop.run_forever()
Поміщає функцію callback
на самий початок списку задач, щоб вона
почала виконуватися якомога швидше. В метод можна передавати
неасинхронні функції. Цей метод корисний, коли необхідно виконати задачу з мінімальною затримкою, особливо коли потрібен швидкий відгук в асинхронному додатку.
Метод call_later(delay, callback, *args)
Планує виклик функції callback
з аргументами *args
через delay
секунд.
import asyncio
def my_callback():
print("Callback executed after delay")
loop = asyncio.get_event_loop()
loop.call_later(2, my_callback)
loop.run_forever()
Цей метод дозволяє виконати відкладений виклик функції: першим параметром передається затримка в секундах (може бути дробною), а далі — посилання на функцію і її параметри. В метод можна передавати неасинхронні функції. Цей метод можна використовувати для керування виконанням задач з різним ступенем терміновості, що корисно при проектуванні складних асинхронних систем.
Метод call_at(when, callback, *args)
Планує виклик функції callback
з аргументами *args
в момент
часу when
.
import asyncio
import time
def my_callback():
print("Callback executed at specific time")
loop = asyncio.get_event_loop()
when = loop.time() + 2 # Через 2 секунди від поточного часу циклу подій
loop.call_at(when, my_callback)
loop.run_forever()
Якщо ви хочете запустити задачу не через 5 секунд, а, наприклад, о
15:00 або 24:00, то вам зручніше буде скористатися
функцією call_at()
, яка працює так само, як
функція call_soon()
, але першим параметром в неї
передається не тривалість паузи, а час, в який потрібно викликати
задану функцію. В метод можна передавати неасинхронні функції.
Переваги та особливості
Асинхронне виконання: Цикл подій дозволяє виконувати багато задач паралельно, не блокуючи основний потік виконання.
Ефективне управління ресурсами: Асинхронні операції введення-виведення виконуються без блокування, роблячи програми більш ефективними.
Гнучкість і масштабованість: Цикл подій підтримує багато методів для планування задач і обробки подій, що дозволяє створювати складні і масштабовані асинхронні додатки.
6.3 Взаємодія з задачами і майбутніми об'єктами
Цикл подій керує виконанням задач (Tasks) і майбутніх об'єктів (Futures). Він відстежує їх стан і забезпечує їх виконання по мірі готовності.
Приклад:
import asyncio
async def main():
await asyncio.sleep(1)
print("Task completed")
loop = asyncio.get_event_loop()
task = loop.create_task(main())
loop.run_until_complete(task)
У цьому прикладі показано, як цикл подій керує виконанням задачі, створеної за допомогою методу create_task
. Методи call_soon()
, call_later()
і call_at()
можна використовувати для керування виконанням задач з різним ступенем терміновості, що корисно при проектуванні складних асинхронних систем.