asyncio — асинхронний планувальник вводу/виводу

Цей модуль забезпечує кооперативний планувальник багатозадачності для корутин async/await, а також примітиви синхронізації (замки, події) і неблокуюче TCP-мережування через потоки читання та запису. Завдання виконуються паралельно в одному циклі подій; поточне завдання передає керування назад до циклу за допомогою await.

Приклад:

import asyncio

async def blink(led, period_ms):
    while True:
        led.on()
        await asyncio.sleep_ms(5)
        led.off()
        await asyncio.sleep_ms(period_ms)

async def main(led1, led2):
    asyncio.create_task(blink(led1, 700))
    asyncio.create_task(blink(led2, 400))
    await asyncio.sleep_ms(10_000)

# Running on an OpenMV Cam
from machine import LED
asyncio.run(main(LED(1), LED(2)))

Основні функції

asyncio.create_task(coro: Coroutine) Task

Створює нове завдання із зазначеної корутини та планує його виконання.

Повертає відповідний об’єкт Task.

asyncio.current_task() Task

Повертає об’єкт Task, пов’язаний з поточним виконуваним завданням.

asyncio.run(coro: Coroutine) Any

Створює нове завдання із зазначеної корутини та виконує його до завершення.

Повертає значення, повернене coro.

asyncio.sleep(t: float) None

Призупиняє виконання на t секунд (може бути числом з плаваючою крапкою).

Це корутина.

asyncio.sleep_ms(t: int) None

Призупиняє виконання на t мілісекунд.

Це корутина та розширення MicroPython.

Додаткові функції

asyncio.wait_for(awaitable: Awaitable, timeout: float) Any

Очікує завершення awaitable, але скасовує його, якщо воно займає більше ніж timeout секунд. Якщо awaitable не є завданням, із нього буде створено завдання.

Якщо час очікування вичерпано, завдання скасовується і виникає виняток asyncio.TimeoutError: його має перехопити виклик. Завдання отримує asyncio.CancelledError, який можна ігнорувати або перехопити за допомогою try...except чи try...finally для виконання коду завершення.

Повертає значення, повернене awaitable.

Це корутина.

asyncio.wait_for_ms(awaitable: Awaitable, timeout: int) Any

Аналогічна wait_for(), але timeout задається цілим числом у мілісекундах.

Це корутина та розширення MicroPython.

asyncio.gather(*awaitables, return_exceptions: bool = False) List

Виконує всі awaitables паралельно. Будь-які awaitables, що не є завданнями, підвищуються до завдань.

Повертає список значень, повернених усіма awaitables.

Це корутина.

class Task

class asyncio.Task

Цей об’єкт обертає корутину в активне завдання. На завдання можна очікувати за допомогою await task, що чекатиме завершення завдання та повертатиме його результат.

Завдання не слід створювати безпосередньо — для цього використовуйте create_task().

cancel() None

Скасовує завдання, вводячи до нього asyncio.CancelledError. Завдання може ігнорувати цей виняток. Код завершення можна виконати, перехопивши його або використавши try ... finally.

class Event

class asyncio.Event

Створює нову подію, яка може використовуватися для синхронізації завдань. Події починаються в очищеному стані.

is_set() bool

Повертає True, якщо подію встановлено, інакше False.

set() None

Встановлює подію. Усі завдання, що очікують на подію, буде заплановано до виконання.

Примітка: виклик має здійснюватися зсередини завдання. Небезпечно викликати це з переривання, зворотного виклику планувальника або іншого потоку. Дивіться ThreadSafeFlag.

clear() None

Очищає подію.

wait() None

Очікує встановлення події. Якщо подію вже встановлено, повертається негайно.

Це корутина.

class ThreadSafeFlag

class asyncio.ThreadSafeFlag

Створює новий прапорець, який може використовуватися для синхронізації завдання з кодом, що виконується поза циклом asyncio, наприклад в інших потоках, перериваннях або зворотних викликах планувальника. Прапорці починаються в очищеному стані.

set() None

Встановлює прапорець. Якщо є завдання, що очікує на прапорець, воно буде заплановано до виконання.

clear() None

Очищає прапорець. Це може використовуватися, щоб переконатися, що можливо раніше встановлений прапорець очищено перед очікуванням на нього.

wait() None

Очікує встановлення прапорця. Якщо прапорець уже встановлено, повертається негайно. Прапорець автоматично скидається після повернення з wait.

На прапорець може очікувати лише одне завдання одночасно.

Це корутина.

class Lock

class asyncio.Lock

Створює новий замок, який можна використовувати для координації завдань. Замки починаються у розблокованому стані.

Окрім наведених нижче методів, замки можна використовувати в операторі async with.

locked() bool

Повертає True, якщо замок заблоковано, інакше False.

acquire() bool

Очікує, поки замок перейде у розблокований стан, а потім атомарно блокує його. Лише одне завдання може захопити замок одночасно.

Це корутина.

release() None

Звільняє замок. Якщо є завдання, що очікують замок, наступне у черзі планується до виконання, а замок залишається заблокованим. Інакше завдань, що очікують, немає, і замок переходить у розблокований стан.

TCP-потокові з’єднання

asyncio.open_connection(host: str, port: int, ssl: ssl.SSLContext | bool | None = None) Tuple[Stream, Stream]

Відкриває TCP-з’єднання до зазначеного host і port. Адреса host буде розпізнана за допомогою socket.getaddrinfo(), що наразі є блокуючим викликом. Якщо ssl є об’єктом ssl.SSLContext, цей контекст використовується для створення транспорту; якщо ssl дорівнює True, використовується типовий контекст.

Повертає пару потоків: потік читання та потік запису. Якщо хост не вдалося розпізнати або з’єднання не вдалося встановити, виникне специфічний для сокетів виняток OSError.

Це корутина.

asyncio.start_server(callback: Callable, host: str, port: int, backlog: int = 5, ssl: ssl.SSLContext | None = None) Server

Запускає TCP-сервер на зазначеному host і port. callback буде викликатися для вхідних прийнятих з’єднань і отримуватиме 2 аргументи: потоки читання та запису для цього з’єднання.

Якщо ssl є об’єктом ssl.SSLContext, цей контекст використовується для створення транспорту.

Повертає об’єкт Server.

Це корутина.

class asyncio.Stream

Цей клас представляє TCP-потокове з’єднання. Щоб мінімізувати код, клас реалізує і читача, і записувача, а StreamReader і StreamWriter є псевдонімами цього класу.

get_extra_info(v: str) Any

Отримує додаткову інформацію про потік, задану параметром v. Допустимі значення v: peername.

close() None

Закриває потік.

wait_closed() None

Очікує закриття потоку.

Це корутина.

read(n: int = -1) bytes

Читає до n байт і повертає їх. Якщо n не вказано або дорівнює -1, читає всі байти до EOF. Якщо EOF зустрінуто до читання будь-яких байт, повертається порожній об’єкт bytes.

Це корутина.

readinto(buf: bytearray | memoryview) int

Читає до n байт у buf, де n дорівнює довжині buf.

Повертає кількість байт, прочитаних у buf.

Це корутина та розширення MicroPython.

readexactly(n: int) bytes

Читає рівно n байт і повертає їх як об’єкт bytes.

Якщо потік завершується до читання n байт, виникає виняток EOFError.

Це корутина.

readline() bytes

Читає рядок і повертає його.

Це корутина.

write(buf: bytes) None

Накопичує buf у вихідному буфері. Дані записуються лише під час виклику Stream.drain(). Рекомендується викликати Stream.drain() одразу після виклику цієї функції.

drain() None

Записує (дренує) всі буферизовані вихідні дані у потік.

Це корутина.

class asyncio.Server

Цей клас представляє сервер, повернений функцією start_server(). Його можна використовувати в операторі async with для закриття сервера під час виходу.

close() None

Закриває сервер.

wait_closed() None

Очікує закриття сервера.

Це корутина.

Цикл подій

asyncio.get_event_loop() Loop

Повертає цикл подій, що використовується для планування та виконання завдань. Дивіться Loop.

asyncio.new_event_loop() Loop

Скидає цикл подій і повертає його.

Примітка: оскільки MicroPython має лише один цикл подій, ця функція лише скидає стан циклу, а не створює новий.

class asyncio.Loop

Цей об’єкт планує та виконує завдання. Його не можна створити безпосередньо — використовуйте get_event_loop().

create_task(coro: Coroutine) Task

Створює завдання із зазначеного coro і повертає новий об’єкт Task.

run_forever() None

Запускає цикл подій до виклику stop().

run_until_complete(awaitable: Awaitable) Any

Виконує зазначений awaitable до його завершення. Якщо awaitable не є завданням, воно буде підвищено до нього.

stop() None

Зупиняє цикл подій.

close() None

Закриває цикл подій.

set_exception_handler(handler: Callable) None

Встановлює обробник винятків, який викликається, коли завдання породжує незловлений виняток. handler має приймати два аргументи: (loop, context).

get_exception_handler() Callable | None

Отримує поточний обробник винятків. Повертає обробник або None, якщо користувацький обробник не встановлено.

default_exception_handler(context: dict) None

Типовий обробник винятків, що викликається.

call_exception_handler(context: dict) None

Викликає поточний обробник винятків. Аргумент context передається як є і є словником з ключами: 'message', 'exception', 'future'.