一、進程(Process)
-
什麼是進程?
進程(有時被稱爲重量級進程)是程序的一次執行。
每個進程都有自己的地址空間,內存,數據棧以及其它記錄其運行軌跡的輔助數據。操作系統管理在其上運行的所有進程,併爲這些進程公平地分配時間。進程也可以通過fork 和spawn 操作來完成其它的任務。不過各個進程有自己的內存空間,數據棧等,所以只能使用進程間通訊(IPC),而不能直接共享信息。
多進程模式最大的優點就是穩定性高,因爲一個子進程崩潰了,不會影響主進程和其他子進程。(當然主進程掛了所有進程就全掛了,但是主進程只負責分配任務,掛掉的概率低)Apache最早就是採用多進程模式。
多進程模式的缺點是創建進程的代價大,在Unix/Linux系統下,用fork調用還行,在Windows下創建進程開銷巨大。另外,操作系統能同時運行的進程數也是有限的,在內存和CPU的限制下,如果有幾千個進程同時運行,操作系統連調度都會成問題。
二、線程(threading)
-
什麼是線程?
線程(有時被稱爲輕量級進程)跟進程有些相似,不同的是,所有的線程運行在同一個進程中,共享相同的運行環境。它們可以想像成是在主進程或“主線程”中並行運行的“迷你進程”。線程有開始,順序執行和結束三部分。它有一個自己的指令指針,記錄自己運行到什麼地方。
線程的運行可能被搶佔(中斷),或暫時的被掛起(也叫睡眠),讓其它的線程運行,這叫做讓步。一個進程中的各個線程之間共享同一片數據空間,所以線程之間可以比進程之間更方便地共享數據以及相互通訊。
線程一般都是併發執行的,正是由於這種並行和數據共享的機制使得多個任務的合作變爲可能。實際上,在單CPU 的系統中,真正的併發是不可能的,每個線程會被安排成每次只運行一小會,然後就把CPU 讓出來,讓其它的線程去運行。
在進程的整個運行過程中,每個線程都只做自己的事,在需要的時候跟其它的線程共享運行的結果。
當然,這樣的共享並不是完全沒有危險的。如果多個線程共同訪問同一片數據,則由於數據訪問的順序不一樣,有可能導致數據結果的不一致的問題。這叫做競態條件(race condition)。幸運的是,大多數線程庫都帶有一系列的同步原語,來控制線程的執行和數據的訪問。
另一個要注意的地方是,由於有的函數會在完成之前阻塞住,在沒有特別爲多線程做修改的情況下,這種“貪婪”的函數會讓CPU 的時間分配有所傾斜。導致各個線程分配到的運行時間可能不盡相同,不盡公平。
多線程模式通常比多進程快一點,但是也快不到哪去,而且,多線程模式致命的缺點就是任何一個線程掛掉都可能直接造成整個進程崩潰,因爲所有線程共享進程的內存。在Windows上,如果一個線程執行的代碼出了問題,你經常可以看到這樣的提示:“該程序執行了非法操作,即將關閉”,其實往往是某個線程出了問題,但是操作系統會強制結束整個進程。
三、協程(gevent)
-
什麼是協程?
協程,又稱微線程,纖程。英文名Coroutine。子程序,或者稱爲函數,在所有語言中都是層級調用,比如A調用B,B在執行過程中又調用了C,C執行完畢返回,B執行完畢返回,最後是A執行完畢。
所以子程序調用是通過棧實現的,一個線程就是執行一個子程序。
子程序調用總是一個入口,一次返回,調用順序是明確的。而協程的調用和子程序不同。
協程看上去也是子程序,但執行過程中,在子程序內部可中斷,然後轉而執行別的子程序,在適當的時候再返回來接着執行。
-
協程的特點在於是一個線程執行,那和多線程比,協程有何優勢?
最大的優勢就是協程極高的執行效率。因爲子程序切換不是線程切換,而是由程序自身控制,因此,沒有線程切換的開銷,和多線程比,線程數量越多,協程的性能優勢就越明顯。
第二大優勢就是不需要多線程的鎖機制,因爲只有一個線程,也不存在同時寫變量衝突,在協程中控制共享資源不加鎖,只需要判斷狀態就好了,所以執行效率比多線程高很多。
參考一個gevent併發編程協程的例子
https://blog.csdn.net/qq_35061334/article/details/95766918
四、拓展:
多任務的實現方式:
- 多進程模式;
- 多線程模式;
- 多進程+多線程模式。
- 多進程+多協程