Python异步/等待执行时间的差异

时间:2019-03-21 12:37:22

标签: python python-3.x async-await python-asyncio

我正在使用异步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秒

为什么会这样?

1 个答案:

答案 0 :(得分:3)

在第一个示例中,您在Ask处创建,等待它完成,然后创建另一个任务,然后等待该另一个任务完成。您正在依次执行任务

在第二个示例中,您要创建两个任务,然后在两个任务都创建之后,等待两个任务完成。您正在同时执行任务

一个任务接一个执行需要花费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() not 等待任务,因为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

请注意 Schedule nested()即将与“ main()” 同时运行,或者只需等待其完成即可。注释。 >

任务是专门的Future子类,因此documentation for asyncio.Future在这里也很重要:

  

未来是一个可以等待的对象。协程可以等待Future对象,直到它们具有结果或异常集,或者直到它们被取消为止。

相关问题