首頁  >  文章  >  後端開發  >  python中線程與進程的區別與優劣

python中線程與進程的區別與優劣

乌拉乌拉~
乌拉乌拉~原創
2018-08-23 17:42:402111瀏覽

在這篇文章之中我們來了解一下什麼是python執行緒與進程。了解python執行緒與進程的相關知識,以及了解一下python中執行緒與進程#的差異與優劣。

我們介紹了多進程和多線程,這是實現多任務最常用的兩種方式。現在,讓我們來討論一下這兩種方式的優缺點。

首先,要實現多任務,通常我們會設計Master-Worker模式,Master負責分配任務,Worker負責執行任務,因此,多任務環境下,通常是一個Master,多個Worker。

如果用多行程實作Master-Worker,主行程就是Master,其他行程就是Worker。

如果用多執行緒實作Master-Worker,主執行緒就是Master,其他執行緒就是Worker。

多進程模式最大的優點就是穩定性高,因為一個子進程崩潰了,不會影響主進程和其他子進程。 (當然主進程掛了所有進程就全掛了,但是Master進程只負責分配任務,掛掉的機率低)著名的Apache最早就是採用多進程模式。

多重處理模式的缺點是建立流程的代價大,在Unix/Linux系統下,用fork呼叫還行,在Windows下建立流程開銷巨大。另外,作業系統能同時運行的進程數也是有限的,在記憶體和CPU的限制下,如果有幾千個進程同時運行,作業系統連調度都會成問題。

多執行緒模式通常比多行程快一點,但是也快不到哪去,而且,多執行緒模式致命的缺點就是任何一個執行緒掛掉都可能直接造成整個行程崩潰,因為所有執行緒共享進程的記憶體。在Windows上,如果一個執行緒執行的程式碼出了問題,你經常可以看到這樣的提示:“該程式執行了非法操作,即將關閉”,其實往往是某個執行緒出了問題,但是作業系統會強制結束整個進程。

在Windows下,多執行緒的效率比多進程要高,所以微軟的IIS伺服器預設採用多執行緒模式。由於多執行緒存在穩定性的問題,IIS的穩定性就不如Apache。為了緩解這個問題,IIS和Apache現在又有多進程 多執行緒的混合模式,真是把問題越搞越複雜。

線程切換

無論是多進程還是多線程,只要數量一多,效率肯定上不去,為什麼呢?

我們打個比方,假設你不幸正在準備中考,每天晚上需要做語文、數學、英語、物理、化學這5科的作業,每項作業耗時1小時。

如果你先花1小時做語言作業,做完了,再花1小時做數學作業,這樣,依序全部做完,一共花5小時,這種方式稱為單任務模型,或者批處理任務模型。

假設你打算切換到多任務模型,可以先做1分鐘語文,再切換到數學作業,做1分鐘,再切換到英語,以此類推,只要切換速度足夠快,這種方式就和單核心CPU執行多任務是一樣的了,以幼稚園小朋友的眼光來看,你就正在同時寫5科作業。

但是,切換作業是有代價的,例如從語文切到數學,要先收拾桌子上的語文書本、鋼筆(這叫保存現場),然後,打開數學課本、找出圓規直尺(這叫準備新環境),才能開始做數學作業。作業系統在切換進程或執行緒時也是一樣的,它需要先保存目前執行的現場環境(CPU暫存器狀態、記憶體頁等),然後,把新任務的執行環境準備好(恢復上次的暫存器狀態,切換記憶體頁等),才能開始執行。這個切換過程雖然很快,但是也需要耗費時間。如果有幾千個任務同時進行,作業系統可能就主要忙著切換任務,根本沒有多少時間去執行任務了,這種情況最常見的就是硬碟狂響,點視窗無反應,系統處於假死狀態。

所以,多任務一旦多到一個限度,就會消耗掉系統所有的資源,結果效率急劇下降,所有任務都做不好。

運算密集型 vs. IO密集型

##

是否採用多任務的第二個考慮是任務的類型。我們可以把任務分為運算密集型和IO密集型。

計算密集型任務的特點是要進行大量的運算,消耗CPU資源,例如計算圓周率、對影片進行高清解碼等等,全靠CPU的運算能力。這種運算密集型任務雖然也可以用多任務完成,但是任務越多,花在任務切換的時間就越多,CPU執行任務的效率就越低,所以,要最高效地利用CPU,計算密集型任務同時進行的數量應等於CPU的核心數。

計算密集型任務由於主要消耗CPU資源,因此,程式碼運行效率至關重要。 Python這樣的腳本語言運作效率很低,完全不適合運算密集型任務。對於計算密集型任務,最好用C語言編寫。

第二種任務的類型是IO密集型,涉及網路、磁碟IO的任務都是IO密集型任務,這類任務的特徵是CPU消耗很少,任務的大部分時間都在等待IO操作完成(因為IO的速度遠低於CPU和記憶體的速度)。對於IO密集型任務,任務越多,CPU效率越高,但也有一個限度。常見的任務大多是IO密集型任務,例如Web應用。

IO密集型任務執行期間,99%的時間都花在IO上,花在CPU上的時間很少,因此,用運行速度極快的C語言替換用Python這樣運行速度極低的腳本語言,完全無法提升運作效率。對於IO密集型任務,最適合的語言就是開發效率最高(程式碼量最少)的語言,腳本語言是首選,C語言最差。

非同步IO

考慮到CPU和IO之間巨大的速度差異,一個任務在執行的過程中大部分時間都在等待IO操作,單進程單執行緒模型會導致別的任務無法並行執行,因此,我們才需要多進程模型或多執行緒模型來支援多任務並發執行。

現代作業系統對IO操作已經做了巨大的改進,最大的特點就是支援非同步IO。如果充分利用作業系統提供的非同步IO支持,就可以用單進程單執行緒模型來執行多任務,這種全新的模型稱為事件驅動模型,Nginx就是支援非同步IO的Web伺服器,它在單核心CPU上採用單進程模型就可以有效率地支援多任務。在多核心CPU上,可以運行多個進程(數量與CPU核心數相同),充分利用多核心CPU。由於系統總的進程數量十分有限,因此作業系統調度非常有效率。用非同步IO程式設計模型來實現多任務是一個主要的趨勢。

對應到Python語言,單執行緒的非同步程式設計模型稱為協程,有了協程的支持,就可以基於事件驅動編寫高效的多任務程式。

以上就是本篇文章所講述的所有內容,這篇文章主要介紹了python中線程與進程的區別於優劣,希望你能藉助資料從而理解上述所說的內容。希望我在這片文章所講述的內容能夠對你有幫助,讓你學習python更加輕鬆。

更多相關知識,請造訪php中文網Python教學欄位。

以上是python中線程與進程的區別與優劣的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn