MicroPython:Библиотеки/uasyncio: различия между версиями
Myagkij (обсуждение | вклад) (Новая страница: «{{MicroPython/Панель перехода}} {{Перевод от Сubewriter}} {{Myagkij-редактор}} <syntaxhighlight lang="python" enclose="div"> =...») |
Нет описания правки |
||
(не показана 1 промежуточная версия 1 участника) | |||
Строка 3: | Строка 3: | ||
{{Myagkij-редактор}} | {{Myagkij-редактор}} | ||
=uasyncio – планировщик для асинхронных операций ввода/вывода<ref>[http://docs.micropython.org/en/latest/library/uasyncio.html docs.micropython.org - uasyncio — asynchronous I/O scheduler]</ref>= | |||
В этом модуле реализована часть функционала соответствующего модуля CPython. Более подробно читайте в документации к CPython о модуле [https://docs.python.org/3.8/library/asyncio.html asyncio]. | |||
<syntaxhighlight lang="python" | Пример: | ||
<syntaxhighlight lang="python"> | |||
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))) | |||
</syntaxhighlight> | |||
==Ключевые функции== | |||
* 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). Адрес хоста можно узнать при помощи функции [https://docs.python.org/3.5/library/socket.html#socket.getaddrinfo 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'. | |||
=См.также= | =См.также= |
Текущая версия от 18:17, 14 мая 2023
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'.