1. 程式人生 > >多程序、多執行緒、協程

多程序、多執行緒、協程

多程序、多執行緒:

多程序模式最大的優點就是穩定性高,因為一個子程序崩潰了,不會影響主程序和其他子程序。(當然主程序掛了所有程序就全掛了,但是Master程序只負責分配任務,掛掉的概率低)著名的Apache最早就是採用多程序模式。
多程序模式的缺點是建立程序的代價大,在Unix/Linux系統下,用fork呼叫還行,在Windows下建立程序開銷巨大。另外,作業系統能同時執行的程序數也是有限的,在記憶體和CPU的限制下,如果有幾千個程序同時執行,作業系統連排程都會成問題。
多執行緒模式通常比多程序快一點,但是也快不到哪去,而且,多執行緒模式致命的缺點就是任何一個執行緒掛掉都可能直接造成整個程序崩潰,因為所有執行緒共享程序的記憶體。在Windows上,如果一個執行緒執行的程式碼出了問題,你經常可以看到這樣的提示:“該程式執行了非法操作,即將關閉”,其實往往是某個執行緒出了問題,但是作業系統會強制結束整個程序。
在Windows下,多執行緒的效率比多程序要高,所以微軟的IIS伺服器預設採用多執行緒模式。由於多執行緒存在穩定性的問題,IIS的穩定性就不如Apache。為了緩解這個問題,IIS和Apache現在又有多程序+多執行緒的混合模式,真是把問題越搞越複雜。

多工一旦多到一個限度,就會消耗掉系統所有的資源
如果有幾千個任務同時進行,作業系統可能就主要忙著切換任務,根本沒有多少時間去執行任務了

任務越多,花在任務切換的時間就越多,CPU執行任務的效率就越低,所以,要最高效地利用CPU,計算密集型任務同時進行的數量應當等於CPU的核心數。

python執行緒的GIL:
GIL即全域性直譯器鎖,它使得python的多執行緒無法充分利用
多核的優勢,但是對於I/O操作頻繁的爬蟲之類的程式,
利用多執行緒帶來的優勢還是很明顯的。
如果要利用多核優勢,還是用多程序吧。
Python的預設直譯器CPython雖然不能利用多執行緒實現多核任務,但可以通過多程序實現多核任務。多個Python程序有各自獨立的GIL鎖,互不影響。

多執行緒和多程序最大的不同在於,多程序中,同一個變數,各自有一份拷貝存在於每個程序中,互不影響,而多執行緒中,所有變數都由所有執行緒共享,所以,任何一個變數都可以被任何一個執行緒修改。
因此要加鎖,獲得鎖的執行緒用完後一定要釋放鎖,否則那些苦苦等待鎖的執行緒將永遠等待下去,成為死執行緒。所以我們用try...finally來確保鎖一定會被釋放。

http://yangcongchufang.com/%E9%AB%98%E7%BA%A7python%E7%BC%96%E7%A8%8B%E5%9F%BA%E7%A1%80/python-process-thread.html#Python中的程序和執行緒
https://www.cnblogs.com/cnkai/p/7504980.html#關於join
 

非同步io(協程):

子程式呼叫是通過棧實現的,一個執行緒就是執行一個子程式。
子程式呼叫總是一個入口,一次返回,呼叫順序是明確的。而協程的呼叫和子程式不同。
協程看上去也是子程式,但執行過程中,在子程式內部可中斷,然後轉而執行別的子程式,在適當的時候再返回來接著執行。
多執行緒比,協程有何優勢?
最大的優勢就是協程極高的執行效率。因為子程式切換不是執行緒切換,而是由程式自身控制,因此,沒有執行緒切換的開銷,和多執行緒比,執行緒數量越多,協程的效能優勢就越明顯。
第二大優勢就是不需要多執行緒的鎖機制,因為只有一個執行緒,也不存在同時寫變數衝突,在協程中控制共享資源不加鎖,只需要判斷狀態就好了,所以執行效率比多執行緒高很多。
因為協程是一個執行緒執行,那怎麼利用多核CPU呢?最簡單的方法是多程序+協程,既充分利用多核,又充分發揮協程的高效率,可獲得極高的效能。

單程序單執行緒模型來執行多工,這種全新的模型稱為事件驅動模型,Nginx就是支援非同步IO的Web伺服器,它在單核CPU上採用單程序模型就可以高效地支援多工。在多核CPU上,可以執行多個程序(數量與CPU核心數相同),充分利用多核CPU。
對應到Python語言,單執行緒的非同步程式設計模型稱為協程。