Python 线程和进程和协程总结
Python 線程和進程和協程總結
線程和進程和協程
進程
進程是程序執行時的一個實例,是擔當分配系統資源(CPU時間、內存等)的基本單位;
進程有獨立的地址空間,一個進程崩潰后,在保護模式下不會對其它進程產生影響;
進程間可以通過信號、信號量、共享內存、管道、隊列等來進行通信;
進程創建、銷毀、上下文切換帶來的開銷成本都很大;
線程
線程是進程的一個實體,作為獨立運行和獨立調度的基本單位。
線程可與同屬一個進程的其他的線程共享進程所擁有的全部資源。
線程只是一個進程中的不同執行路徑,沒有單獨的地址空間,一個線程死掉就會導致整個進程死掉。
線程創建、銷毀、上下文切換帶來的開銷要比進程小得多;
協程
協程的控制有應用程序控制,非搶占式的;
切換快,開銷相較線程更小,所以可以開更多的協程;
具體使用參考Python 協程總結
多線程和多進程
多線程
優點
它是一種非常"節儉"的多任務操作方式。我們知道,在Linux系統下,啟動一個新的進程必須分配給它獨立的地址空間,建立眾多的數據表來維護它的代碼段、堆棧段和數據段,這是一種"昂貴"的多任務工作方式。而運行于一個進程中的多個線程,它們彼此之間使用相同的地址空間,共享大部分數據,啟動一個線程所花費的空間遠遠小于啟動一個進程所花費的空間,而且,線程間彼此切換所需的時間也遠遠小于進程間切換所需要的時間。
線程間方便的通信機制,對不同進程來說,它們具有獨立的數據空間,要進行數據的傳遞只能通過通信的方式進行,這種方式不僅費時,而且很不方便。線程則不然,由于同一進程下的線程之間共享數據空間,所以一個線程的數據可以直接為其它線程所用。
提高應用程序響應。這對圖形界面的程序尤其有意義,當一個操作耗時很長時,整個系統都會等待這個操作,此時程序不會響應鍵盤、鼠標、菜單的操作,而使用多線程技術,將耗時長的操作(time consuming)置于一個新的線程,可以避免這種尷尬的情況。
使多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、多線程、多進程
轉載于:https://www.cnblogs.com/George1994/p/10615435.html
總結
以上是生活随笔為你收集整理的Python 线程和进程和协程总结的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JavaWeb——c:forEach v
- 下一篇: python 游戏 —— 汉诺塔(Han