執行緒與並行模型

執行緒與行程的差別

把行程想成一整間公寓,有自己的大門、自己的家具、自己上鎖的房間,裡面的東西鄰居的公寓完全看不到。執行緒則是住在那間公寓裡的一個人。你可以讓好幾個人(執行緒)共住一間公寓(行程):他們走同樣的走廊、用同一個廚房、讀同一個書架。要跟另一間公寓的人說話,你得敲門、隔著門遞東西(這就是行程間通訊);要跟室友說話,你隔著房間講話就行(這就是共享記憶體)。

具體來說,行程是一個正在執行的程式,連同它自己私有的位址空間和自己的資源:程式碼、資料、堆積、已開啟檔案清單等等。作業系統把一個行程的記憶體與另一個隔離開來,所以一個行程裡的錯誤或當機通常不會破壞另一個行程。執行緒則是某個行程內部的一條執行流。一個行程的所有執行緒共享那一份位址空間與那些資源,而每個執行緒只各自保有自己的堆疊、暫存器和程式計數器。所以最大的差別在於「什麼是私有的」:行程擁有一整個獨立的世界,執行緒只擁有足以記住自己做到哪裡的那一點點。

這就解釋了大家在意的取捨。建立一個執行緒比建立一個行程便宜很多,因為不必設置新的位址空間。在同一行程的兩個執行緒之間切換 CPU,比在不同行程之間切換便宜,因為昂貴的記憶體對映狀態維持不變。執行緒之間的通訊很快(共享記憶體)但預設不安全;行程之間的通訊比較安全(有隔離)但比較慢(要經過核心)。要誠實說明的一點是:讓行程比較安全的那種隔離,正是讓執行緒有風險的原因,一個執行緒亂寫記憶體,就可能破壞同一行程裡每一個其他執行緒的資料。

把兩個瀏覽器視窗開成兩個行程,意味著一個視窗當機不會拖垮另一個,因為它們彼此隔離。但若兩個分頁是同一行程裡的兩個執行緒,一旦有錯誤失控就可能互相破壞,這正是現代瀏覽器實際上會把每個網站放進各自行程的原因之一。

行程隔離換來安全,執行緒共享換來速度。

一個常見的混淆:執行緒不是越多越好。它們透過共享記憶體協調起來更便宜、更快,但會犧牲掉獨立行程所提供的故障隔離。

又称
thread versus process執行緒對行程