python-3.x - 为什么等待任务比等待协程更快?
问题描述
为什么等待任务比等待协程更快?
我正在查看文档https://docs.python.org/3/library/asyncio-task.html
特别是这个例子:
等待任务
async def say_after(delay, what):
await asyncio.sleep(delay)
print(what)
async def main():
task1 = asyncio.create_task(
say_after(1, 'hello'))
task2 = asyncio.create_task(
say_after(2, 'world'))
print(f"started at {time.strftime('%X')}")
# Wait until both tasks are completed (should take
# around 2 seconds.)
await task1
await task2
print(f"finished at {time.strftime('%X')}")
与协程
import asyncio
import time
async def say_after(delay, what):
await asyncio.sleep(delay)
print(what)
async def main():
print(f"started at {time.strftime('%X')}")
await say_after(1, 'hello')
await say_after(2, 'world')
print(f"finished at {time.strftime('%X')}")
asyncio.run(main())
解决方案
等待任务并没有真正比等待协程更快。当您使用时,asyncio.create_task
您正在为给定函数创建一个新任务,因此 python 为该函数创建一个任务并转到下一行。当您正在等待一项任务时,您只是在等待它完成。
import asyncio
async def task(delay, id):
print(f'task with the id of {id} created (delay: {delay})')
await asyncio.sleep(delay) # some calculation the takes time
print(f'task {id} finished the heavy calculation')
async def main(loop):
task1 = asyncio.create_task(task(3, 1))
task2 = asyncio.create_task(task(5, 2))
task3 = asyncio.create_task(task(1, 3))
loop = asyncio.get_event_loop()
loop.run_until_complete(main(loop))
loop.run_forever()
正如您在这段代码中看到的,我们没有等待任务完成,每个任务都花时间完成。
解释:
task1
- 创建一个立即执行该功能的任务task2
- 创建任务1后创建任务(创建未完成,同时task1功能仍在运行)task3
- 在创建所有任务后创建(同时运行 task1/2 的功能)main
函数完成执行并关闭loop.run_forver()
不让程序结束- 任务的输出
如果您删除该程序,loop.run_forever()
则该程序将在不等待任务完成的情况下关闭,这就是为什么有时await
您需要执行任务,因为您需要该值。
例如(相同的代码更改主函数):
async def main(loop):
task1 = asyncio.create_task(task(3, 1))
task2 = asyncio.create_task(task(5, 2))
task3 = asyncio.create_task(task(1, 3))
x = await task1
loop = asyncio.get_event_loop()
loop.run_until_complete(main(loop))
这只会等待 task1 完成并退出代码(没有loop.run_forever()
)。
推荐阅读
- php - Understrap 自定义博客页面 - 不清楚哪个页面以及在哪里修改
- python - Pandas 忽略 json 正文中的标题和列
- tensorflow - 在卷积神经网络中计算维度
- python - 为什么我得到我不想要的句子?以及如何纠正它?
- sql - 识别 SQL 中 2 列组合的唯一性
- c# - 如何将变量从一个函数放到另一个函数
- laravel - Laravel - 销毁然后更新deleted_by
- javascript - firebase查询后数组不保存值的问题
- android - Flutter - 如何获得刷新的 Firebase 的应用令牌
- azure-functions - 在每个月的特定日期运行脚本 azure