Python 線程和進程和協程總結

Python 線程和進程和協程總結

線程和進程和協程

進程

  • 進程是程序執行時的一個實例,是擔當分配系統資源(CPU時間、內存等)的基本單位;html

  • 進程有獨立的地址空間,一個進程崩潰後,在保護模式下不會對其它進程產生影響;python

  • 進程間能夠經過信號、信號量、共享內存、管道、隊列等來進行通訊;web

  • 進程建立、銷燬、上下文切換帶來的開銷成本都很大;多線程

線程

  • 線程是進程的一個實體,做爲獨立運行和獨立調度的基本單位。spa

  • 線程可與同屬一個進程的其餘的線程共享進程所擁有的所有資源。操作系統

  • 線程只是一個進程中的不一樣執行路徑,沒有單獨的地址空間,一個線程死掉就會致使整個進程死掉。線程

  • 線程建立、銷燬、上下文切換帶來的開銷要比進程小得多;協程

協程

  • 協程的控制有應用程序控制,非搶佔式的;htm

  • 切換快,開銷相較線程更小,因此能夠開更多的協程;blog

具體使用參考Python 協程總結

多線程和多進程

多線程

優勢

  1. 它是一種很是"節儉"的多任務操做方式。咱們知道,在Linux系統下,啓動一個新的進程必須分配給它獨立的地址空間,創建衆多的數據表來維護它的代碼段、堆棧段和數據段,這是一種"昂貴"的多任務工做方式。而運行於一個進程中的多個線程,它們彼此之間使用相同的地址空間,共享大部分數據,啓動一個線程所花費的空間遠遠小於啓動一個進程所花費的空間,並且,線程間彼此切換所需的時間也遠遠小於進程間切換所須要的時間。

  2. 線程間方便的通訊機制,對不一樣進程來講,它們具備獨立的數據空間,要進行數據的傳遞只能經過通訊的方式進行,這種方式不只費時,並且很不方便。線程則否則,因爲同一進程下的線程之間共享數據空間,因此一個線程的數據能夠直接爲其它線程所用。

  3. 提升應用程序響應。這對圖形界面的程序尤爲有意義,當一個操做耗時很長時,整個系統都會等待這個操做,此時程序不會響應鍵盤、鼠標、菜單的操做,而使用多線程技術,將耗時長的操做(time consuming)置於一個新的線程,能夠避免這種尷尬的狀況。

  4. 使多CPU系統更加有效。操做系統會保證當前線程數不大於CPU數目時,不一樣的線程運行於不一樣的CPU上。

GIL

全局解釋器鎖是在實現Python解析器(CPython)時所引入的一個概念。每一個線程在執行的過程都須要先獲取GIL,保證同一時刻只有一個線程能夠執行代碼。

Q&A: 爲何說GIL對於CPU密集型任務不友好,而對於IO密集型任務比較友好呢?

這是由於GIL的釋放邏輯是當前線程碰見IO操做或者ticks計數達到100(ticks能夠看做是python自身的一個計數器,專門作用於GIL,每次釋放後歸零,這個計數能夠經過 sys.setcheckinterval 來調整),進行釋放。而每次釋放GIL鎖,線程進行鎖競爭、切換線程,會消耗資源。

那CPU密集型任務(各類循環處理、計數等等),在這種狀況下,ticks計數很快就會達到閾值,而後觸發GIL的釋放與再競爭(多個線程來回切換固然是須要消耗資源的),可是對於IO密集型任務,多線程可以有效提高效率(單線程下有IO操做會進行IO等待,形成沒必要要的時間浪費,而開啓多線程能在線程A等待時,自動切換到線程B,能夠不浪費CPU的資源,從而能提高程序執行效率)。所以說GIL對於CPU密集型任務不友好,而對於IO密集型任務比較友好。

解決方案

multiprocessing庫的出現很大程度上是爲了彌補thread庫由於GIL而低效的缺陷,它完整的複製了一套thread所提供的接口方便遷移。惟一的不一樣就是它使用了多進程而不是多線程。每一個進程有本身的獨立的GIL,所以也不會出現進程之間的GIL爭搶。固然multiprocessing也不是萬能良藥。它的引入會增長程序實現時線程間數據通信和同步的困難。Python的多線程在多核CPU上,只對於IO密集型計算產生正面效果;而當至少有一個CPU密集型線程存在時,那麼多線程效率會因爲GIL而大幅降低,這個時候就得使用多進程;

多進程

Python中的多線程由於GIL的關係並不算是真正的多線程,若是想要充分地使用多核CPU的資源,大部分狀況須要使用多進程。multiprocessing支持子進程、通訊和共享數據、執行不一樣形式的同步,提供了Process、Queue、Pipe、Lock等組件。

談談python的GIL、多線程、多進程

相關文章
相關標籤/搜索