Python 模塊 asyncio-協程之間的同步

Python 模塊 asyncio-協程之間的同步

雖然 asyncio 是運行在單線程模型上的,但是它的每個協程可能執行的順序是不一致的,這要看超時、IO、網絡或者其他的資源使用情況。所以 asyncio 為了支持安全的併發,從模塊 threading 和 multiprocessing 引入了一些處理併發的單元。

鎖 Locks


鎖被用來保護訪問的資源,只有獲取鎖後才可以訪問資源,同一時間只有一個協程可以獲取鎖。

Python 模塊 asyncio-協程之間的同步

執行:

Python 模塊 asyncio-協程之間的同步

本例創建了兩個協程,他們分別以兩種方式獲取和釋放鎖,一種使用 async with lock 語法,它會自動釋放鎖,另一種直接調用獲取鎖的方法 await lock.acquire(),然後使用 try:finally 釋放鎖。

因為 main() 協程一開始就獲取鎖了,需要等到 unlock() 方法執行釋放鎖後,兩個協程才能獲取鎖。

事件 Events


asyncio.Event 基於 threading.Event,只有事件對象內部標誌位設置了,其他的才會繼續往下執行。

Python 模塊 asyncio-協程之間的同步

執行:

Python 模塊 asyncio-協程之間的同步

本例中,一開始的兩個協程 c1() 和 c2() 等待事件對象被設置,當事件對象狀態改變時,立刻執行。

條件 Conditions


條件(Condition)同步機制和 Events 類似,當調用 notify() 時,等待的協程就開始執行。

Python 模塊 asyncio-協程之間的同步

執行:

Python 模塊 asyncio-協程之間的同步

本例創建了5個消費者協程等待 Condition,wait() 直到所有的消費者協程執行完後才繼續往下運行。manipulate_condition() 首先是釋放了兩個協程,然後使用 notify_all() 釋放全部。

隊列 Queues


asyncio.Queue 是一個 FIFO(first-in first-out)的數據結構,和 queue.Queue、multiprocessing.Queue 一樣。

Python 模塊 asyncio-協程之間的同步

執行:

Python 模塊 asyncio-協程之間的同步

調用隊列的 get() 和 put() 方法時,都需要 await,因為他們都是異步操作,從隊列獲取元素有可能隊列為空,添加元素可能隊列元素數量已經達到最大值。


分享到:


相關文章: