我正在使用异步 io 对两种执行方法进行计时
案例 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秒
为什么会这样?
最佳答案
在第一个示例中,您在询问时创建,等待它完成,然后创建另一个任务,并等待另一个任务完成。您正在按顺序执行任务。
在第二个示例中,您正在创建两个任务,然后在它们都创建后等待这两个任务完成。您正在同时执行任务。
任务一个接一个执行需要 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
直到任务已经完成。
Tasks section of the Awaitables documentation 中有一个示例:
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()”同时运行 和或者可以简单地等待直到它完成评论。 p>
任务是专门的 Future
子类,所以 documentation for asyncio.Future
在这里也相关:
Future is an awaitable object. Coroutines can await on Future objects until they either have a result or an exception set, or until they are cancelled.
关于Python 异步/等待执行时间的差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55280608/