鍍金池/ 問答/Java  Python  C  Linux  網絡安全/ 關于asyncio 執(zhí)行過程的問題。內含代碼,對執(zhí)行順序有點不解

關于asyncio 執(zhí)行過程的問題。內含代碼,對執(zhí)行順序有點不解

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)

執(zhí)行結果:
Waiting: 1
Waiting: 2
Waiting: 4
(這里隔了四秒)
Task ret: Done after 1s
Task ret: Done after 2s
Task ret: Done after 4s
TIME: 4.007018804550171

代碼是網上復制的,不理解的是結果中那個停留了四秒。 按小白的理解,執(zhí)行到第一個await asyncio.sleep(x)的時候跳 到第二個阻塞了又到第三個,然后第三個阻塞了不是應該跳回第一個嗎? 然后跳 回函數內執(zhí)行FRO循環(huán)。會先打印第一個出來 然后兩秒后再打印第二個,然后四秒后再打印第四個。
上面的執(zhí)行結果變成是等最后一個四秒結束后,一起for出來了。這里不理解? 求大佬解惑

回答
編輯回答
逗婦乳
dones, pendings = await asyncio.wait(tasks)
這里是要匯總所有的結果,而你task里使用的是return 相當于等3個人做作業(yè),
要等最慢的一個交完作業(yè),當然是4s結束之后才有了。
如果你直接在task里sleep之后print那么相當于讓做完作業(yè)的人直接舉手,結果就不一樣了。
2017年8月15日 11:55
編輯回答
尐懶貓

condition1,contdition2,condition3是塞在一個隊列里面的,condition1先取出來執(zhí)行,執(zhí)行到sleep,輪到下一個,下一個繼續(xù),一直到最后一個;然后condition1睡好了,開始繼續(xù)往下,執(zhí)行完后,后面的跟上

2017年2月13日 06:36
編輯回答
失心人

你代碼里使用的是:

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

而不是用 print 即時打印
所以邏輯是,運行完畢之后,收集了所有的結果,然后一口氣都打印出來。
如果想要你設想的結果,直接在return前加一句即時打印就好了

要是想看點有趣的, 加個timeout試試,保證不需要等4秒,并且4秒的任務都沒有機會結束,整個程序就結束了:

dones, pendings = await asyncio.wait(tasks, timeout=2)
2017年4月13日 05:54