#python #python-3.x #async-await #python-asyncio
#python #python-3.x #async-ожидание #python-asyncio
Вопрос:
Я рассчитываю время выполнения двух методов, используя асинхронный ввод-вывод
СЛУЧАЙ 1:
async def test():
print(f"started at {time.strftime('%X')}")
await asyncio.create_task(say_after(2, 'hello'))
await asyncio.create_task(say_after(4, 'world'))
print(f"finished at {time.strftime('%X')}")
и это ответ :
started at 12:31:05
hello
world
finished at 12:31:11
всего 6 секунд
СЛУЧАЙ 2:
async def test():
print(f"started at {time.strftime('%X')}")
t1=asyncio.create_task(say_after(2, 'hello'))
t2= asyncio.create_task(say_after(4, 'world'))
await t1
await t2
print(f"finished at {time.strftime('%X')}")
и это ответ :
started at 12:31:05
hello
world
finished at 12:31:09
всего 4 секунды
почему это так?
Комментарии:
1. Поскольку задача начинает выполняться при ее создании, что означает, что ваши задачи будут выполняться «параллельно», если вы сначала создадите обе, а затем будете ожидать их (поскольку первая задача напрямую достигнет своего условия приостановки (
say_after
), а затем разрешит запуск следующей задачи.
Ответ №1:
В первом примере вы создаете по запросу, ждете его завершения, затем создаете другую задачу и ждете завершения этой другой задачи. Вы выполняете задачи последовательно.
Во втором примере вы создаете две задачи, затем, после того как они обе созданы, ожидаете завершения двух. Вы выполняете задачи одновременно.
Выполнение задач друг за другом занимает 2 4 = 6 секунд, но при последовательном выполнении вам нужно подождать всего 4 секунды для завершения второй, более длинной задачи, в то время как более короткая задача за 2 секунды завершена за некоторое время до этого:
# sequentially
| start task 1
V
-------------
| 2 seconds |
-------------
^
await returns |
| start task 2
V
--------------------------
| 4 seconds |
--------------------------
^
await returns |
# consecutively
| start task 1
V
-------------
| 2 seconds |
-------------
^
await returns |
| start task 2
V
--------------------------
| 4 seconds |
--------------------------
^
await returns |
Разница заключается в вызове, asyncio.create_task()
а не в немедленном ожидании выполнения задач, потому что await task
не завершится, пока задача не будет завершена.
В разделеЗадачи«Ожидаемые» приведен пример:
async def main():
# Schedule nested() to run soon concurrently
# with "main()".
task = asyncio.create_task(nested())
# "task" can now be used to cancel "nested()", or
# can simply be awaited to wait until it is complete:
await task
Обратите внимание на расписание nested() для запуска в ближайшее время одновременно с «main()» и или может просто быть отложено, чтобы дождаться завершения комментариев.
Задачи являются специализированными Future
подклассами, поэтому документация для asyncio.Future
здесь тоже уместна:
Future — это ожидаемый объект. Сопрограммы могут ожидать будущих объектов до тех пор, пока у них не будет результата или установленного исключения, или пока они не будут отменены.
Комментарии:
1. в документации следует добавить это, в основном,
await t1
в случае, если 2 не требуется, посколькуawait t2
будет ждать 4 секунды. Спасибо2. @JibinMathews: это зависит от приложения, а не от того, что документация может сказать вам, когда ожидать, а когда нет.