簡體   English   中英

Asyncio 執行流程問題

[英]Asyncio execution flow issue

我對 python 中的 asyncio 有點陌生。 我試圖運行這個簡單的代碼,但我不知道為什么我會得到這個意外的輸出。

我所做的是,在outer函數中,我創建了異步任務並將其存儲在數組tasks 在等待這些任務之前,我寫了一個應該在每次迭代中運行的打印語句print("outer") 在任務中,我在inner函數中編寫了另一個打印語句print("inner") 但是我如何得到一些意想不到的輸出。

這是代碼 -

import asyncio


def main():
    loop = asyncio.get_event_loop()
    loop.run_until_complete(outer(loop))
    loop.close()


async def outer(loop):
    tasks = []
    for i in range(0, 5):
        tasks.append(loop.create_task(inner()))

    for task in tasks:
        print("outer")
        await task


async def inner():
    print("inner")
    await asyncio.sleep(0.5)

if __name__ == '__main__':
    main()

這是輸出 -

outer
inner
inner
inner
inner
inner
outer
outer
outer
outer

我的預期輸出是 -

outer
inner
outer
inner
outer
inner
outer
inner
outer
inner

為什么所有的inner都在outer打印之前。 asyncio 的正確執行流程是什么? 提前致謝。

async def outer(loop)

for i in range(0, 5):
    tasks.append(loop.create_task(inner()))
  • 五個新的inner任務被創建、調度並開始運行。
  • 事件循環運行計划任務直到它們完成。

如果您在innerouter添加更多內容,則可以更好地顯示此過程:

async def outer(loop):
    tasks = []
    for i in range(0, 5):
        tasks.append(loop.create_task(inner(i)))
    await asyncio.sleep(3)
    for task in tasks:
        print('outer')
        await task

async def inner(n):
    print(f"inner {n} start")
    await asyncio.sleep(0.5)
    print(f'inner {n} end')
  • outer睡覺時

    • 第一個任務運行到它的 await 語句
    • 事件循環掛起第一個任務的執行
    • 事件循環運行下一個調度任務直到它的 await 語句
    • 這一直持續到每個任務都有機會運行到它的 await 語句,然后事件循環開始環顧四周,看看是否有任何任務完成,等待他們等待的任何東西——如果完成,它讓它們運行更多。
    • 這一直持續到所有任務完成
  • 您可以看到這五個任務在第二個 for 循環開始之前執行並完成。

  • 在第二個 for 循環中,每個任務都已經完成,所以await task沒有什么可等待的,並且outer連續打印五次。

我對控制一切的事件循環有點模糊 - 我沒有找到任何明確的文檔 - 可能在create_task文檔中提到: Wrap the coro coroutine into a Task and schedule its execution. 當您創建任務時,它會被安排。 我在 pyvideo.org 上看過顯示該過程的視頻,不幸的是我無法快速找到我想要鏈接的視頻。

loop.create_task(inner())立即將所有 5 個inner任務排隊await task運行,而不是await task await task outer掛起直到第一個任務完成,即至少 0.5 秒。 在此期間,所有inner任務都運行了一次await ,包括它們的print


async def outer(loop):
    tasks = []
    for i in range(0, 5):
        # queues task immediately
        tasks.append(loop.create_task(inner()))

    for task in tasks:
        print("outer")
        # suspends for at least 0.5 seconds
        await task


async def inner():
    # runs immediately
    print("inner")
    await asyncio.sleep(0.5)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM