8.16. Подведение итогов¶
Вы прошли через API asyncio – части, которые нужны скрипту для одновременного выполнения нескольких задач на одном CPU:
Кооперативное планирование – модель, на которой держится остальная часть модуля. Выполняющаяся сопрограмма единолично владеет циклом, пока не выполнит
await; переключения происходят только в этих точках await.Сопрограммы и задачи –
async defопределяет единицу работы;asyncio.create_task()планирует её для конкурентного выполнения и возвращаетTask, которую приложение может позднее ждать, отменить или идентифицировать.Цикл событий – движок, который выполняет сопрограммы и задачи.
asyncio.run()– единственная точка входа, нужная большинству скриптов; классLoopпредоставляет остальное для редких случаев, когда это требуется.Координация –
gather()для разветвления и сбора,wait_for()для крайних сроков,Task.cancelи шаблон очистки в предложенииfinally, распространение исключений через задачи и вызовы gather, а также хук обработчика исключений цикла.Примитивы синхронизации –
Eventдля сигнализации между сопрограммами,Lockдля сериализации доступа к общему ресурсу между операциями await иThreadSafeFlagдля пробуждения задачи asyncio из обработчика прерывания.Пользовательские асинхронные объекты – языковые хуки, которые позволяют классам приложения встраиваться в идиомы asyncio.
__await__для объектов, которые сами являются цельюawait,__aiter__/__anext__дляasync forи__aenter__/__aexit__дляasync with.Захват кадров – обёртка, которая превращает
csi.CSI.snapshot()в дружественную кawaitсопрограмму, так что цикл захвата выполняется параллельно с другой работой asyncio.Подводные камни – забытые
await, плотные циклы без передачи управления, проглоченные отмены, общее состояние, изменяемое между операциями await, и прочие специфичные для asyncio ловушки.
Этого достаточно, чтобы писать программы, сочетающие работу с камерой, аппаратный ввод-вывод и конкурентную фоновую работу в одном цикле.
8.16.1. Использование этого справочника в дальнейшем¶
Относитесь к главам про asyncio как к справочному материалу; возвращение за формой async with или точным поведением gather() при сбое одной из соседних задач – это и есть предполагаемое использование. Справочная страница модуля asyncio перечисляет каждую функцию и класс в одном месте, когда вопрос состоит лишь в том, «как именно называется этот вызов».
Для более богатых примитивов, построенных поверх модуля – семафоров, очередей, барьеров и солидной коллекции вспомогательных средств прикладного назначения – стандартным источником, поддерживаемым сообществом, является репозиторий peterhinch/micropython-async.
8.16.2. Куда двигаться дальше¶
Работа с сетью – следующая крупная тема. asyncio.open_connection(), asyncio.start_server() и класс Stream – это то, как скрипт asyncio общается с остальной частью сети изнутри сопрограммы, вместе с лежащими в основе модулями network и socket. Всё, что вы узнали об await, Task, отмене и примитивах синхронизации, переносится сюда напрямую.