关于asyncio 执行过程的问题。内含代码,对执行顺序有点不解

import asyncio
 
import time
 
now = lambda: time.time()
 
async def do_some_work(x):
    print('Waiting: ', x)
 
    await asyncio.sleep(x)
    return 'Done after {}s'.format(x)
 
async def main():
    coroutine1 = do_some_work(1)
    coroutine2 = do_some_work(2)
    coroutine3 = do_some_work(4)
 
    tasks = [
        asyncio.ensure_future(coroutine1),
        asyncio.ensure_future(coroutine2),
        asyncio.ensure_future(coroutine3)
    ]
 
    dones, pendings = await asyncio.wait(tasks)
 
    for task in dones:
        print('Task ret: ', task.result())
 
start = now()
 
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
 
print('TIME: ', now() - start)

执行结果:
Waiting: 1
Waiting: 2
Waiting: 4
(这里隔了四秒)
Task ret: Done after 1s
Task ret: Done after 2s
Task ret: Done after 4s
TIME: 4.007018804550171

代码是网上复制的,不理解的是结果中那个停留了四秒。 按小白的理解,执行到第一个await asyncio.sleep(x)的时候跳 到第二个阻塞了又到第三个,然后第三个阻塞了不是应该跳回第一个吗? 然后跳 回函数内执行FRO循环。会先打印第一个出来 然后两秒后再打印第二个,然后四秒后再打印第四个。
上面的执行结果变成是等最后一个四秒结束后,一起for出来了。这里不理解? 求大佬解惑

阅读 5.2k
3 个回答

condition1,contdition2,condition3是塞在一个队列里面的,condition1先取出来执行,执行到sleep,轮到下一个,下一个继续,一直到最后一个;然后condition1睡好了,开始继续往下,执行完后,后面的跟上

你代码里使用的是:

return 'Done after {}s'.format(x)

而不是用 print 即时打印
所以逻辑是,运行完毕之后,收集了所有的结果,然后一口气都打印出来。
如果想要你设想的结果,直接在return前加一句即时打印就好了

要是想看点有趣的, 加个timeout试试,保证不需要等4秒,并且4秒的任务都没有机会结束,整个程序就结束了:

dones, pendings = await asyncio.wait(tasks, timeout=2)
dones, pendings = await asyncio.wait(tasks)
这里是要汇总所有的结果,而你task里使用的是return 相当于等3个人做作业,
要等最慢的一个交完作业,当然是4s结束之后才有了。
如果你直接在task里sleep之后print那么相当于让做完作业的人直接举手,结果就不一样了。
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题