Как правильно создавать и запускать параллельные задачи с помощью модуля Python asyncio?

Я пытаюсь правильно понять и реализовать два одновременно работающихTask объекты, использующие относительно новый Python 3asyncio модуль.

Короче говоря, Asyncio, кажется, предназначен для обработки асинхронных процессов и одновременныхTask выполнение по циклу событий. Это способствует использованиюawait (применяется в асинхронных функциях) как способ без обратного вызова для ожидания и использования результата, не блокируя цикл событий. (Фьючерсы и обратные вызовы по-прежнему являются жизнеспособной альтернативой.)

Это также обеспечиваетasyncio.Task() класс, специализированный подклассFuture предназначен для упаковки сопрограмм. Предпочтительно вызывается с помощьюasyncio.ensure_future() метод. Предполагаемое использование асинхронных задач - позволить независимо выполняющимся задачам запускаться «одновременно» с другими задачами в рамках одного и того же цикла событий. Я понимаю, чтоTasks подключены к циклу событий, который затем автоматически продолжает движение сопрограммы междуawait заявления.

Мне нравится идея использовать одновременные задачи без необходимости использовать один изExecutor классы, но я не нашел много разработок по реализации.

Вот как я сейчас это делаю:

import asyncio

print('running async test')

async def say_boo():
    i = 0
    while True:
        await asyncio.sleep(0)
        print('...boo {0}'.format(i))
        i += 1

async def say_baa():
    i = 0
    while True:
        await asyncio.sleep(0)
        print('...baa {0}'.format(i))
        i += 1

# wrap in Task object
# -> automatically attaches to event loop and executes
boo = asyncio.ensure_future(say_boo())
baa = asyncio.ensure_future(say_baa())

loop = asyncio.get_event_loop()
loop.run_forever()

В случае одновременного запуска двух циклических задач я заметил, что если в задаче нет внутреннегоawait выражение, оно застрянет вwhile цикл, эффективно блокирующий выполнение других задач (очень похоже на обычныйwhile петля). Однако, как только Задачам приходится (а) ждать, они, похоже, работают одновременно без проблем.

Таким образомawait операторы, кажется, обеспечивают цикл событий опорой для переключения между задачами, создавая эффект параллелизма.

Пример вывода с внутреннейawait:

running async test
...boo 0
...baa 0
...boo 1
...baa 1
...boo 2
...baa 2

Пример выводабез внутреннийawait:

...boo 0
...boo 1
...boo 2
...boo 3
...boo 4
Вопросы

Проходит ли эта реализация «правильный» пример параллельных циклических задач вasyncio?

Верно ли, что это работает только дляTask обеспечить точку блокировки (await выражение) для того, чтобы цикл событий манипулировал несколькими задачами?

Ответы на вопрос(0)

Ваш ответ на вопрос