Почему `await asyncio.create_task ()" ведет себя иначе, чем при присвоении его переменной? - PullRequest
0 голосов
/ 12 января 2020

Почему в задачах 1-3 и 4-6 по-разному выполняются задачи в приведенном ниже коде?

Код:

import asyncio


async def do_something(i, sleep):  # No I/O here
    print("Doing... ", end="")
    print(await no_io_1(i, sleep))


async def no_io_1(i, sleep):  # No I/O here
    return await no_io_2(i, sleep)


async def no_io_2(i, sleep):  # No I/O here
    return await io(i, sleep)


async def io(i, sleep):
    await asyncio.sleep(sleep)  # Finally some I/O
    # t = asyncio.create_task(asyncio.sleep(sleep))
    # await t
    return i


async def main():
    await asyncio.create_task(do_something(1, sleep=4))
    await asyncio.create_task(do_something(2, sleep=3))
    await asyncio.create_task(do_something(3, sleep=2))

    t4 = asyncio.create_task(do_something(4, sleep=4))
    t5 = asyncio.create_task(do_something(5, sleep=3))
    t6 = asyncio.create_task(do_something(6, sleep=2))
    await t4
    await t5
    await t6

asyncio.run(main())
print("\r\nBye!")

Вывод:

Doing... 1
Doing... 2
Doing... 3
Doing... Doing... Doing... 6
5
4

1 Ответ

2 голосов
/ 12 января 2020

В первом фрагменте вы сразу ожидаете каждую созданную вами задачу. В результате задачи не могут выполняться параллельно.

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

Другими словами, await t1 не означает "запуск * 1007". * ", это означает" приостановить меня и раскрутить событие l oop, пока t1 не будет сделано ". Разница не имеет ничего общего с задачами, хранящимися в переменных, но с одновременным созданием задач. Например, вы можете изменить второй пример следующим образом:

    t4 = asyncio.create_task(do_something(4, sleep=4))
    await t4
    t5 = asyncio.create_task(do_something(5, sleep=3))
    await t5
    t6 = asyncio.create_task(do_something(6, sleep=2))
    await t6

... и вы получите поведение, подобное первому примеру.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...