Я намагаюся правильно зрозуміти та реалізувати два одночасно запущені Task
об'єкти, використовуючи відносно новий asyncio
модуль Python 3 .
У двох словах, asyncio, здається, призначений для обробки асинхронних процесів та одночасного Task
виконання через цикл подій. Він сприяє використанню await
(застосовується в асинхронних функціях) як способу зворотного виклику для очікування та використання результату, не блокуючи цикл подій. (Ф'ючерси та зворотні виклики все ще є життєздатною альтернативою.)
Він також надає asyncio.Task()
клас, спеціалізований підклас, Future
призначений для обгортання програм. Переважно викликати за допомогою asyncio.ensure_future()
методу. Призначене використання завдань asyncio - дозволити незалежно запущеним завданням виконуватись "одночасно" з іншими завданнями в тому ж циклі події. Я розумію, що 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
вираз) для того, щоб цикл подій жонглював кількома завданнями?
yield from
наступногоyield from
.