python併發學習 asyncio包解析

2021-08-22 14:48:29 字數 1152 閱讀 6072

asyncio中future、task和協程之間的關係

asyncio為什麼與協程一起使用

協程中的yield關鍵字,不管資料如何流動,都是一種流程控制工具,使用它可以實現協作式多工;協程可以把控制器讓步給中心排程程式,從而啟用其他的協程。

協程中的yield from語句能夠開啟雙向通道,把最外層的事件迴圈和內部的真正執行耗時操作的i/o函式連線起來,這樣兩者可以直接傳送和產出值,還可以直接傳入異常,而不用在中間的協程中新增大量處理異常的樣板**。有了這個結構,協程可以通過以前不可能的方式委派職責。當最內層的i/o操作執行結束並返回時,直譯器會丟擲stopiteration異常,並把返回值附加到異常物件,yield from能夠捕獲stopiteration異常並獲取返回值,此時恢復中間層的協程的執行。這就實現了事件迴圈、中間層協程和內層的耗時的子生成器之間的非阻塞型排程。

asyncio包中能夠建立task物件的函式

asyncio驅動的事件迴圈為什麼不會阻塞

事件迴圈loop呼叫方法loop.run_until_complete(…)驅動傳入的引數,它的引數是乙個future或者協程。如果是協程,run_until_complete方法和wait函式一樣,把協程包裝進乙個task物件中。協程、future和任務(task)都由yield from驅動,這正是run_until_complete方法對其引數所做的事情。

yield from foo句法能夠防止阻塞,是因為當前協程(即包括yield from**的委派生成器)暫停後,控制權回到事件迴圈手中,再去驅動其它協程;foo future或協程執行結束後,把結果返回到暫停的協程(yield from自動捕獲stopiteration),將其恢復。

這樣,最外層的事件迴圈始終可以不被阻塞,併發地排程所有協程向前推進。

阻塞型i/o和gil

cpython直譯器本身就不是執行緒安全的,因此有全域性直譯器鎖(gil),一次只會允許使用乙個執行緒執行python位元組碼。一次,乙個python程序通常不能同時使用多個cpu核心。

然而,標準庫中所有執行阻塞型i/o操作的函式,在等待作業系統返回結果時都會釋放gil。這意味著在python語言這個層次上可以使用多執行緒,而i/o密集型python程式能從中受益:乙個python執行緒等待網路響應時,阻塞型i/o函式會釋放gil,在執行乙個執行緒。

async和enterproxy控制併發數量

相對於併發,並行可能陌生了不少,並行指一組程式按獨立非同步的速度執行,不等於時間上的重疊 同乙個時刻發生 通過增加cpu核心來實現多個程式 任務 的同時進行。沒錯,並行做到了多工的同時進行 enterproxy是樸靈大大為主要貢獻的工具,帶來一種事件式程式設計的思維變化,利用事件機制解耦複雜業務邏輯...

Python學習 25 併發程式設計

併發 程序 process 執行緒 thread 全域性直譯器鎖 gil global interpreter lock 多執行緒 開始執行緒 start new thread function,args,kwargs none threading 模組 啟動執行緒 start 要求主線程等待 jo...

python併發程式設計調優 python併發程式設計

併發程式設計是我們程式設計中常用的優化程式效能的手段,能提高cpu的使用率。一般使用是多執行緒,多程序,協程 一 python的全域性解釋鎖gil 我們目前跑的python程式大多數都是在cpython上執行的。cpython是有乙個全域性解釋鎖,具體什麼意思,可以兩個方面理解 在同一時刻,只能執行...