標籤:自動 多進程 講解 跳轉 alt 檔案 上下文 狀態 結果
協程是python中除了進程和線程之外又一種能夠實現多任務的方式,又稱為微線程,纖程,它相比於線程需要的資源更少。
在python種協程是通過generator實現的。通過yield儲存當前啟動並執行狀態然後切換到另一個協程執行。普通的生產者-消費這模式是一個線程寫訊息,一個線程才能讀取訊息,因此需要控制隊列的寫入與讀取資料。而改用協程可以在生產者生產訊息後直接通過yield跳轉到消費者開始執行,執行完畢後在切換到生產者,如此反覆,效率極高。
在圖中,我們可以看出通過next的方法使得產生器中的任務完成了交替執行,實現了多任務。
注意,在協程類比中,相較於線程沒法設計運行順序,協程是可以設計執行的順序的。這樣協程之間就能協作完成任務,而不會如線程一樣得搶佔資源。
由於協程得切換隻是簡單得操作CPU得上下文,因此系統甚至在1s中切換幾百萬次都毫無壓力。
在python中為了更好得使用協程來完成任務,可以使用python中greenlet模組和gevent。greenlet在協程切換需要人工切換,因此主要給大家介紹gevent這個強大且能自動切換任務的模組。
在講解gevent模組直接,大家需要先瞭解一下協程主要發力的領域,那就是非同步IO。
我們都知道CPU得執行速度很快,每秒幾百萬次幾千萬次得速度小菜一碟。在IO操作得時候,如讀寫檔案,發送網路資料等,都需要等待IO操作才能執行下面的代碼,這種情況就叫做同步IO。在IO操作得過程中,當前的線程是被掛起的,下面的代碼需要等待IO操作完成才能執行。如網路通訊send資料,和recv資料得過程實際上都在等待伺服器回應。這個時候就需要使用多線程或多進程來並發執行代碼,但是,線程和進程得開銷很大,如果需要切換的次數較多,反而降低了效率。所以我們為了能夠充分利用線程阻塞得這段時間繼續使CPU工作(要知道被阻塞1s中CPU就少計算幾百萬次),可以使用非同步IO的方法:當代碼執行到一個IO操作得時候,它只發出IO指令,並不等待結果,而去執行其他得代碼,當IO響應的時候在返回處理,這樣當有頻繁得IO操作得時候,將會大大增加程式得執行效率。
直到非同步IO得概念後,gevent的原理就很好理解了。我們還是以程式為例
在work這個方法中,用gevent.sleep(1)來類比線程阻塞1s的情況,從 程式結果可以看出,當線程遇到阻塞會執行下個協程,等到阻塞結束才會回去處理
python中協程