Python asyncio задача не запускается - PullRequest
0 голосов
/ 19 ноября 2018

Я пытаюсь понять Python Asyncio Lib, но это боль, и каждый раз, когда я думаю, что я знаю, как код будет себя вести, что-то меня удивляет.

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

async def a():
    while True:
        task = asyncio.current_task()  # asyncio.Task.current_task()
        print(task.name)
        await asyncio.sleep(0.5)

async def main():
    tasks = []

    for i in range(10):
        c = a()
        task = asyncio.create_task(c)
        task.name = "task nr {}".format(i)
        tasks.append(task)

    for task in tasks:
        await task

asyncio.run(main())

Результатом будет следующий подозрительный вывод:

task nr 0
task nr 1
task nr 2
task nr 3
task nr 4
task nr 5
task nr 6
task nr 7
task nr 8
task nr 9

и так далее.С другой стороны, у меня есть код

async def a():
    while True:
        task = asyncio.current_task()  # asyncio.Task.current_task()
        print(task.name)
        await asyncio.sleep(0.5)

async def main():

    for i in range(10):
        c = a()
        task = asyncio.create_task(c)
        task.name = "task nr {}".format(i)
        await task

asyncio.run(main())

. На этот раз он выводит просто "task nr 0".

В первом случае создается 10 задач, а затем запускаются все из них.Второй объединяет эти два цикла - почему это влияет на поведение программы?

Ответы [ 2 ]

0 голосов
/ 19 ноября 2018

Второй объединяет эти два цикла - почему это влияет на поведение программы?

Поскольку ваш первый код запускает create_task для всех десяти сопрограмм перед этимполучение await.

Поскольку create_task планирует выполнение сопрограммы, в первом примере все десять сопрограмм счастливо выполняются параллельно, пока вы ожидаете первую (которая, как и другой ответ) указывает на , никогда не завершится, потому что сопрограммы бесконечны).Во втором цикле вы выполняете только one create_task до бесконечного ожидания, поэтому вы запускаете только одну сопрограмму.

Если вы знакомы с потоками, возможно, следующая аналогия поможет: Вы можете думать о create_task как о порождении потока, а await как о присоединении к нему.В первом примере вы породили десять из них, а во втором только один.

0 голосов
/ 19 ноября 2018

Ваш a() - бесконечная сопрограмма. Процесс его ожидания никогда не будет завершен. Это означает, что в вашем втором фрагменте цикл for никогда не войдет в следующую итерацию. Это в основном "заблокировано" навсегда на await task.

...