Блокировка нескольких асинхронных вызовов


Мой код:

import asyncio

async def test(i):
    await asyncio.sleep(i)
    print('test')

async def main():
    await test(2)
    await test(2)
    await test(2)

asyncio.get_event_loop().run_forever(main())

Я ожидал, что он будет спать в течение трех секунд, а затем распечатает 'test' три раза, но вместо этого он ждет 2 секунды, прежде чем каждый 'test' отдельно (так что последний 'test' печатается через 6 секунд).

Что я понял неправильно, и как я могу исправить это, чтобы работать, как я ожидал?

1 3

1 ответ:

await приостанавливает выполнение текущей функции до тех пор, пока не вернется будущее. В test, это заставляет функцию ждать в течение 2 секунд, пока asyncio.sleep не вернется, прежде чем печатать. В main он заставляет функцию ждать, пока test не вернется (что она делает после print, что она делает после sleep возвратилась), прежде чем продолжить на следующей строке со следующим await test.

Если вы хотите выполнить все test одновременно и заставить их печатать одновременно через две секунды, вы можете используйте asyncio.gather:

async def main():
    await asyncio.gather(test(2), test(2), test(2))

Это планирование трех test сопрограмм в цикле событий одновременно и ожидает всех их Объединенных результатов, которые прибудут через ~2 секунды.

Вы также можете стрелять и забыть о сорутинах, не дожидаясь их завершения:

def main():
    asyncio.ensure_future(test(2))
    asyncio.ensure_future(test(2))
    asyncio.ensure_future(test(2))