Python 线程和进程和协程总结
Python 線程和進(jìn)程和協(xié)程總結(jié)
線程和進(jìn)程和協(xié)程
進(jìn)程
進(jìn)程是程序執(zhí)行時(shí)的一個(gè)實(shí)例,是擔(dān)當(dāng)分配系統(tǒng)資源(CPU時(shí)間、內(nèi)存等)的基本單位;
進(jìn)程有獨(dú)立的地址空間,一個(gè)進(jìn)程崩潰后,在保護(hù)模式下不會(huì)對(duì)其它進(jìn)程產(chǎn)生影響;
進(jìn)程間可以通過(guò)信號(hào)、信號(hào)量、共享內(nèi)存、管道、隊(duì)列等來(lái)進(jìn)行通信;
進(jìn)程創(chuàng)建、銷毀、上下文切換帶來(lái)的開(kāi)銷成本都很大;
線程
線程是進(jìn)程的一個(gè)實(shí)體,作為獨(dú)立運(yùn)行和獨(dú)立調(diào)度的基本單位。
線程可與同屬一個(gè)進(jìn)程的其他的線程共享進(jìn)程所擁有的全部資源。
線程只是一個(gè)進(jìn)程中的不同執(zhí)行路徑,沒(méi)有單獨(dú)的地址空間,一個(gè)線程死掉就會(huì)導(dǎo)致整個(gè)進(jìn)程死掉。
線程創(chuàng)建、銷毀、上下文切換帶來(lái)的開(kāi)銷要比進(jìn)程小得多;
協(xié)程
協(xié)程的控制有應(yīng)用程序控制,非搶占式的;
切換快,開(kāi)銷相較線程更小,所以可以開(kāi)更多的協(xié)程;
具體使用參考Python 協(xié)程總結(jié)
多線程和多進(jìn)程
多線程
優(yōu)點(diǎn)
它是一種非常"節(jié)儉"的多任務(wù)操作方式。我們知道,在Linux系統(tǒng)下,啟動(dòng)一個(gè)新的進(jìn)程必須分配給它獨(dú)立的地址空間,建立眾多的數(shù)據(jù)表來(lái)維護(hù)它的代碼段、堆棧段和數(shù)據(jù)段,這是一種"昂貴"的多任務(wù)工作方式。而運(yùn)行于一個(gè)進(jìn)程中的多個(gè)線程,它們彼此之間使用相同的地址空間,共享大部分?jǐn)?shù)據(jù),啟動(dòng)一個(gè)線程所花費(fèi)的空間遠(yuǎn)遠(yuǎn)小于啟動(dòng)一個(gè)進(jìn)程所花費(fèi)的空間,而且,線程間彼此切換所需的時(shí)間也遠(yuǎn)遠(yuǎn)小于進(jìn)程間切換所需要的時(shí)間。
線程間方便的通信機(jī)制,對(duì)不同進(jìn)程來(lái)說(shuō),它們具有獨(dú)立的數(shù)據(jù)空間,要進(jìn)行數(shù)據(jù)的傳遞只能通過(guò)通信的方式進(jìn)行,這種方式不僅費(fèi)時(shí),而且很不方便。線程則不然,由于同一進(jìn)程下的線程之間共享數(shù)據(jù)空間,所以一個(gè)線程的數(shù)據(jù)可以直接為其它線程所用。
提高應(yīng)用程序響應(yīng)。這對(duì)圖形界面的程序尤其有意義,當(dāng)一個(gè)操作耗時(shí)很長(zhǎng)時(shí),整個(gè)系統(tǒng)都會(huì)等待這個(gè)操作,此時(shí)程序不會(huì)響應(yīng)鍵盤、鼠標(biāo)、菜單的操作,而使用多線程技術(shù),將耗時(shí)長(zhǎng)的操作(time consuming)置于一個(gè)新的線程,可以避免這種尷尬的情況。
使多CPU系統(tǒng)更加有效。操作系統(tǒng)會(huì)保證當(dāng)前線程數(shù)不大于CPU數(shù)目時(shí),不同的線程運(yùn)行于不同的CPU上。
GIL
全局解釋器鎖是在實(shí)現(xiàn)Python解析器(CPython)時(shí)所引入的一個(gè)概念。每個(gè)線程在執(zhí)行的過(guò)程都需要先獲取GIL,保證同一時(shí)刻只有一個(gè)線程可以執(zhí)行代碼。
Q&A: 為什么說(shuō)GIL對(duì)于CPU密集型任務(wù)不友好,而對(duì)于IO密集型任務(wù)比較友好呢?
這是因?yàn)镚IL的釋放邏輯是當(dāng)前線程遇見(jiàn)IO操作或者ticks計(jì)數(shù)達(dá)到100(ticks可以看作是python自身的一個(gè)計(jì)數(shù)器,專門做用于GIL,每次釋放后歸零,這個(gè)計(jì)數(shù)可以通過(guò) sys.setcheckinterval 來(lái)調(diào)整),進(jìn)行釋放。而每次釋放GIL鎖,線程進(jìn)行鎖競(jìng)爭(zhēng)、切換線程,會(huì)消耗資源。
那CPU密集型任務(wù)(各種循環(huán)處理、計(jì)數(shù)等等),在這種情況下,ticks計(jì)數(shù)很快就會(huì)達(dá)到閾值,然后觸發(fā)GIL的釋放與再競(jìng)爭(zhēng)(多個(gè)線程來(lái)回切換當(dāng)然是需要消耗資源的),但是對(duì)于IO密集型任務(wù),多線程能夠有效提升效率(單線程下有IO操作會(huì)進(jìn)行IO等待,造成不必要的時(shí)間浪費(fèi),而開(kāi)啟多線程能在線程A等待時(shí),自動(dòng)切換到線程B,可以不浪費(fèi)CPU的資源,從而能提升程序執(zhí)行效率)。因此說(shuō)GIL對(duì)于CPU密集型任務(wù)不友好,而對(duì)于IO密集型任務(wù)比較友好。
解決方案
multiprocessing庫(kù)的出現(xiàn)很大程度上是為了彌補(bǔ)thread庫(kù)因?yàn)镚IL而低效的缺陷,它完整的復(fù)制了一套thread所提供的接口方便遷移。唯一的不同就是它使用了多進(jìn)程而不是多線程。每個(gè)進(jìn)程有自己的獨(dú)立的GIL,因此也不會(huì)出現(xiàn)進(jìn)程之間的GIL爭(zhēng)搶。當(dāng)然multiprocessing也不是萬(wàn)能良藥。它的引入會(huì)增加程序?qū)崿F(xiàn)時(shí)線程間數(shù)據(jù)通訊和同步的困難。Python的多線程在多核CPU上,只對(duì)于IO密集型計(jì)算產(chǎn)生正面效果;而當(dāng)至少有一個(gè)CPU密集型線程存在時(shí),那么多線程效率會(huì)由于GIL而大幅下降,這個(gè)時(shí)候就得使用多進(jìn)程;
多進(jìn)程
Python中的多線程因?yàn)镚IL的關(guān)系并不算是真正的多線程,如果想要充分地使用多核CPU的資源,大部分情況需要使用多進(jìn)程。multiprocessing支持子進(jìn)程、通信和共享數(shù)據(jù)、執(zhí)行不同形式的同步,提供了Process、Queue、Pipe、Lock等組件。
談?wù)刾ython的GIL、多線程、多進(jìn)程
轉(zhuǎn)載于:https://www.cnblogs.com/George1994/p/10615435.html
總結(jié)
以上是生活随笔為你收集整理的Python 线程和进程和协程总结的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: JavaWeb——c:forEach v
- 下一篇: json-server-----》基本使