MicroPython:Библиотеки/uasyncio

Материал из Онлайн справочника
Версия от 18:17, 14 мая 2023; EducationBot (обсуждение | вклад)
(разн.) ← Предыдущая версия | Текущая версия (разн.) | Следующая версия → (разн.)
Перейти к навигацииПерейти к поиску

Перевод: Максим Кузьмин
Проверка/Оформление/Редактирование: Мякишев Е.А.


uasyncio – планировщик для асинхронных операций ввода/вывода[1]

В этом модуле реализована часть функционала соответствующего модуля CPython. Более подробно читайте в документации к CPython о модуле asyncio.

Пример:

import uasyncio

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

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

# Запуск на pyboard:
from pyb import LED
uasyncio.run(main(LED(1), LED(2)))

# Запуск на стандартной плате:
from machine import Pin
uasyncio.run(main(Pin(1), Pin(2)))

Ключевые функции

  • uasyncio.create_task(coro) – создает новую задачу из заданной сопрограммы и планирует ее запуск. Возвращает соответствующий объект Task (см. ниже).
  • uasyncio.run(coro) – создает новую задачу из заданной сопрограммы, запускает ее и ждет ее завершения. Возвращает значение, возвращенное coro.
  • uasyncio.sleep(t) – режим сна на t секунд (значение в аргументе t может быть числом с плавающей точкой). Это сопрограмма.
  • uasyncio.sleep_ms(t) – режим сна на t миллисекунд. Это сопрограмма, и в CPython этой функции нет, она сделана специально для MicroPython.

Дополнительные функции

  • uasyncio.wait_for(awaitable, timeout) – ждет завершения задачи awaitable, но если время в таймере timeout истечет, задача будет прервана до своего выполнения. Если awaitable – это не задача, то из этого аргумента будет сделана задача.

Если таймаут истечет, задача будет прервана, а затем будет возбуждено исключение asyncio.TimeoutError. Инициатор вызова должен быть готов, чтобы перехватить это исключение. Возвращает значение, возвращенное awaitable. Это сопрограмма.

  • uasyncio.wait_for_ms(awaitable, timeout) – делает то же самое, что и wait_for(), но timeout – это целое число в миллисекундах.

Это сопрограмма, и в CPython ее нет, она сделана специально для MicroPython.

  • uasyncio.gather(\*awaitables, return_exceptions=False) – запускает все awaitables одновременно. Все awaitable, не являющиеся задачами, повышаются до задач.

Возвращает список значений, возвращенных всеми задачами в awaitables. Это сопрограмма.

Класс Task

  • Класс uasyncio.Task – этот объект обертывает сопрограмму в запускаемую задачу. В MicroPython есть функции для ожидания выполнения задач – wait_for() и wait_for_ms() – которые после выполнения задачи возвращают значение, возвращенное этой задачей.

Задачи не должны создаваться напрямую. Используйте для этого функцию create_task().

  • Task.cancel() – отменяет выполнение задачи, внедряя в нее ошибку CancelledError. Задача может проигнорировать это исключение.

Класс Event

  • classuasyncio.Event – создает новое событие, которое можно использовать для синхронизации задач. События запускаются в «очищенном» состоянии.
  • Event.is_set() – возвращает True, если событие находится во «включенном» состоянии, в противном случае возвращает False.
  • Event.set() – переводит событие во «включенное» состояние. Все задачи, ждущие этого события, будут запланированы к запуску.
  • Event.clear() – «очищает» событие.
  • Event.wait() – ждет, пока событие будет переведено во «включенное» состояние. Если событие уже находится в таком состоянии, мгновенно возвращает True.

Это сопрограмма.

Класс Lock

  • Класс uasyncio.Lock – создает новую блокировку, которую можно использовать для координации задач. Блокировки начинают работать в разблокированном состоянии.

Вдобавок к методам ниже, блокировки можно использовать в операторе async with.

  • Lock.locked() – возвращает True, если блокировка заблокирована, а в противном случае возвращает False.
  • Lock.acquire() – ждет, пока блокировка не разблокируется, а затем ставит блокировку. Одновременно блокировку может удерживать только одна сопрограмма.

Это сопрограмма.

  • Lock.release() – снимает блокировку (т.е. перестает ее удерживать). Если при этом есть задачи, ожидающие снятия блокировки, то та из них, что первая стоит в очереди, будет запланирована на запуск, после чего блокировка снова будет активирована. В противном случае не будет разблокирована ни одна задача.

Потоковые TCP-соединения

  • uasyncio.open_connection(host, port) – открывает TCP-соединение, используя заданные хост (host) и порт (port). Адрес хоста можно узнать при помощи функции socket.getaddrinfo(), которая в данный момент является блокирующей функцией.

Возвращает два потока: для чтения и записи. Если не получается узнать адрес хоста или установить соединение, будет выдана сокетная ошибка OSError. Это сопрограмма.

  • uasyncio.start_server(callback, host, port, backlog=5) – запускает TCP-сервер на заданных хосте (host) и порте (port). При каждом подключении к клиенту будет вызвана функция обратного вызова callback, которой для подключения будут переданы два аргумента: потоки для чтения и записи.

Возвращает объект Server (см. ниже). Это сопрограмма.

  • Класс uasyncio.Stream – это класс для потокового TCP-соединения. Чтобы минимизировать код, в этом классе реализованы одновременно классы StreamReader (для чтения) и StreamWriter (для записи).
  • Stream.get_extra_info(v) – считывает дополнительную информацию о потоке v. Пример корректного значения для аргумента v: peername.
  • Stream.close() – закрывает поток.
  • Stream.wait_closed() – ждет закрытия потока. Это сопрограмма.
  • Stream.read(n) – считывает до n байтов и возвращает их. Это сопрограмма.
  • Stream.readline() – считывает строку и возвращает ее. Это сопрограмма.
  • Stream.write(buf) – аккумулирует данные в буфер buf. Данные в буфере будут стерты только после вызова Stream.drain() (см. ниже). Рекомендуется вызывать Stream.drain() сразу после вызова этой функции.
  • Stream.drain() – «иссушает» буфер, т.е. записывает все данные из него в поток. Это сопрограмма.
  • Класс uasyncio.Server – это серверный класс, возвращаемый функцией start_server() (см. выше). Его можно использовать в операторе async with, чтобы закрыть сервер при выходе.
  • Server.close() – закрывает сервер.
  • Server.wait_closed() – ждет закрытия сервера. Это сопрограмма.

Цикл событий

  • uasyncio.get_event_loop() – возвращает цикл событий, использовавшийся для планирования и запуска задач. Более подробно читайте ниже (см. класс Loop).
  • uasyncio.new_event_loop() – сбрасывает цикл событий и возвращает его.

Примечание: Поскольку в MicroPython только один цикл событий, эта функция просто сбрасывает состояния цикла, а не создает новый.

  • Класс uasyncio.Loop – объект для планирования и запуска задач. Создать его нельзя, поэтому чтобы получить доступ к нему, используйте функцию get_event_loop() (см. выше).
  • Loop.create_task(coro) – создает задачу из заданной сопрограммы coro и возвращает новый объект Task.
  • Loop.run_forever() – запускает цикл событий, который будет работать, пока не будет вызвана функция stop().
  • Loop.run_until_complete(awaitable) – запускает заданную awaitable, и она будет работать, пока не завершится. Если объект awaitable – это не задача, то он будет «повышен» до задачи.
  • Loop.stop() – останавливает цикл событий.
  • Loop.close() – закрывает цикл событий.
  • Loop.set_exception_handler(handler) – задает обработчик исключения, который будет вызван, когда задача возбудит невыловленное исключение. Этот обработчик должен принимать два аргумента: (loop, context).
  • Loop.get_exception_handler() – возвращает текущий обработчик исключений или None, если обработчика исключений задано не было.
  • Loop.default_exception_handler(context) – вызывает обработчик исключений, заданный по умолчанию.
  • Loop.call_exception_handler(context) – вызывает текущий обработчик исключений. Аргумент context – это словарь с ключами 'message', 'exception', 'future'.

См.также

Внешние ссылки