asyncio create_task для запуска навсегда - PullRequest
0 голосов
/ 29 мая 2018

У меня есть следующий код

import asyncio

loop = asyncio.get_event_loop()

async def while_loop():
    n = 0
    while True:
        print(f"{n}")
        await asyncio.sleep(2)
        n = n+1

async def some_func():
    await asyncio.sleep(5)
    print("Some Func")

future = loop.create_task(while_loop())
loop.run_until_complete(some_func())

Я ожидал, что функция while_loop будет работать вечно, но, кажется, она выполняется только в результате вызова run_until_complete и перестает печатать цикл while один раз some_func завершено выполнение.Вывод, который я вижу:

0
1
2
Some Func

Я ожидал, что цифры продолжат печататься даже после завершения some_func.

0
1
2
Some Func
3
4
5
6
.
.
.

Единственный способ получить больше напечатанных номеров - это позвонитьsome_func снова.

1 Ответ

0 голосов
/ 29 мая 2018

Я ожидал, что числа продолжат печататься даже после завершения some_func.

Аргумент run_until_complete управляет продолжительностью цикла событий.И как только цикл обработки событий перестает работать, все сопрограммы фактически приостанавливаются, а не только та, которую вы ждали.Но у вас есть разные варианты:

  • loop.run_until_complete(some_func()) - что вы уже использовали;запускайте цикл обработки событий до тех пор, пока не завершится сопрограмма some_func.Выполняет другие сопрограммы параллельно в течение этого времени, но также останавливает их выполнение, как только завершается цикл обработки событий.

  • loop.run_forever() - запустить цикл обработки событийпока какой-нибудь сопрограмма или обратный вызов не вызовет loop.stop().Если никто из них этого не сделает, цикл обработки событий не остановится, даже если все сопрограммы завершатся.В вашем случае вы бы позвонили loop.create_task(while_loop()), затем loop.create_task(some_func()) и затем loop.run_forever().

  • loop.run_until_complete(asyncio.gather(while_loop(), some_func())) запустить цикл обработки событий до тех пор, пока оба не будут указанысопрограммы заканчиваются.Это (подождите все задач), очевидно, то, что вы ожидали, loop.run_until_complete() будет делать автоматически, даже если вы назовете только одну, за исключением того, что она не работает таким образом, она останавливается, как только заканчивается указанная сопрограмма,asyncio.gather можно использовать для ожидания нескольких сопрограмм одновременно.Для более точной настройки ожидания также см. asyncio.wait.

Поскольку одна из ваших сопрограмм работает вечно, последние две опции будут эквивалентны иприведет к ожидаемому результату.

...