天天看點

python asyncio_Python裡的協程——asyncio

asyncio提供的架構以事件循環(event loop) 為中心,程式開啟一個無限的循環,程式會把一些函數注冊到事件循環上。當滿足事件發生的時候,調用相應的協程函數。

事件循環loop調用方法loop.run_until_complete(…)驅動傳入的參數,它的參數是一個future或者協程。協程、future和任務(Task)都由yield from驅動,這正是run_until_complete方法對其參數所做的事情。

yield from function句法能夠防止阻塞,是因為目前協程(即包括yield from代碼的委派生成器)暫停後,控制權回到事件循環手中,再去驅動其它協程; function future或協程運作結束後,把結果傳回到暫停的協程(yield from自動捕獲StopIteration),将其恢複,即最外層的事件循環始終可以不被阻塞,并發地排程所有協程向前推進。

Future

future是一個資料結構,表示還未完成的工作結果。事件循環可以監視Future對象是否完成。進而允許應用的一部分等待另一部分完成一些工作。

Task

Task是Future的一個子類,它知道如何包裝和管理一個協程的執行。

await

await 用于挂起阻塞的異步調用,用于挂起耗時的操作。

使用await可以針對耗時的操作進行挂起,就像生成器裡的yield一樣,函數讓出控制權。協程遇到await,事件循環将會挂起該協程,執行await 後面跟着的那個協程,直到await來的協程也挂起或者執行完畢,再進行下一個協程的執行。

import asyncio

# async關鍵字定義一個協程(coroutine),協程也是一種對象。

# 協程不能直接運作,需要把協程加入到事件循環(loop)

async def func(n):

print('Hello world <{}>'.format(n))

r = await asyncio.sleep(n)

print('hello again <{}>'.format(n))

# asyncio.get_event_loop 方法可以建立一個事件循環。

loop = asyncio.get_event_loop()

# run_until_complete 将協程注冊到事件循環,并啟動事件循環。

# loop.run_until_complete(func(6))

tasks = [func(4), func(5), func(2)]

loop.run_until_complete(asyncio.wait(tasks))

loop.close()

"""

Hello world <5>

Hello world <2>

Hello world <4>

hello again <2>

hello again <4>

hello again <5>

"""