1. 程式人生 > >Python程序、執行緒、協程的對比

Python程序、執行緒、協程的對比

1. 執行過程

  • 每個執行緒有一個程式執行的入口、順序執行序列和程式的出口。但是執行緒不能夠獨立執行,必須依存在程序中,由程序提供多個執行緒執行控制。每個執行緒都有他自己的一組CPU暫存器,稱為執行緒的上下文,該上下文反映了執行緒上次執行該執行緒的CPU暫存器的狀態。
  • 協程,又稱微執行緒,Coroutine。執行過程中,在子程式內部可中斷,然後轉而執行別的子程式,在適當的時候再返回來接著執行。實際上就是對函式呼叫流程的一種控制方式,讓函式互相協作配合,這就是協程。

2. 排程方式

  • 程序和執行緒完全由作業系統負責排程,程式自己不能決定什麼時候執行,執行多長時間。
  • 協程則是在程式中,自己負責排程,更加靈活,但複雜度較高。

3. 執行效率

  • 程序是重量級別的程式,建立和銷燬開銷大。
  • 執行緒是輕量級別的程式,相比程序下建立和銷燬開銷小,切換速度較快。
  • 協程則是單執行緒的非同步程式設計模型。和多執行緒比,執行緒數量越多,CPU就會花掉更多時間在切換中,而沒有執行緒切換、儲存上下文的開銷的協程,相比下執行效率則更高。第二大優勢就是不需要多執行緒的鎖機制,因為只有一個執行緒,也不存在同時寫變數衝突,在協程中控制共享資源不加鎖,所以協程效能優勢更加明顯。

4. CPU利用

  • 執行緒和協程由於CPython中全域性直譯器鎖GIL的問題,只能使用到單核CPU的計算資源
  • 程序則可以執行多個(數量與CPU核心數相同),充分利用多核CPU

CPython直譯器本身不是執行緒安全的,因此需要全域性直譯器鎖GIL,一次只允許一個執行緒執行Python位元組碼。因此一個Python程序不能同時使用到多個CPU核心。
然而,標準庫中所有執行阻塞型 IO 操作的函式,在等待結果返回時都會釋放GIL。這意味著儘管有GIL,Python執行緒還是能在 IO 密集型任務中一展身手。 引用自《流暢的Python》

5. 最佳實踐

  • 執行緒和協程推薦在IO密集型的任務(比如網路呼叫)中使用,而在CPU密集型的任務中,表現較差。
  • 對於CPU密集型的任務,則需要多個程序,繞開GIL的限制,利用所有可用的CPU核心,提高效率。
  • 所以大併發下的最佳實踐就是多程序+協程,既充分利用多核,又充分發揮協程的高效率,可獲得極高的效能。
    順便一提,非常流行的一個爬蟲框架Scrapy就是用到非同步框架Twisted來進行任務的排程,這也是Scrapy框架高效能的原因之一。


作者:chaosmind
連結:https://www.jianshu.com/p/0ec911909dff
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯絡作者獲得授權並註明出處。