行程與執行緒的差異:比較記憶體、切換與使用時機

行程是擁有專屬位址空間與資源、正在執行的程式。執行緒是行程中的執行單位。同一個行程的執行緒共用記憶體,因此建立成本小、通訊也快,但一個錯誤或異常終止會影響整個行程。不同的行程彼此隔離,較為安全,但建立的成本以及行程間通訊的成本都比較大。

項目行程執行緒
是什麼擁有專屬位址空間與檔案等資源、正在執行的程式行程中的執行流程。擁有自己的堆疊與暫存器
記憶體各自獨立的虛擬位址空間。與其他行程隔離共用行程的程式碼、堆積與全域資料。專屬的只有堆疊
建立成本重。必須準備新的位址空間(可利用寫入時複製來降低成本)輕。不需要新的位址空間
情境切換高。位址空間會改變,位址轉換結果的快取(TLB)可能失效便宜。位址空間與快取維持不變
通訊需要管線、通訊端、共用記憶體等行程間通訊可直接讀寫共用記憶體,速度快
隔離與故障異常終止多半只限於該行程之內一個執行緒的異常終止,可能牽連整個行程
同步在行程之間共用記憶體或檔案時需要共用資料時一律需要。若沒有互斥鎖或不可分割操作,就會發生資料競爭或死結
排程包含一個以上的執行緒由作業系統實際分配給CPU核心的單位
主要用途為了隔離與安全。瀏覽器的分頁、服務、Shell的管線單一程式內的平行處理。處理大量連線的伺服器、背景處理、平行運算

數值為具代表性的大致參考值,會因世代或產品而異。

適用於什麼情況

行程
需要隔離、強健性與安全性時。或是由不同開發者製作的軟體不可共用記憶體時。
執行緒
處理之間必須快速共用資料,且想在一個程式中使用多個CPU核心時。
注意
執行緒共用記憶體,既是優點也是風險。共用資料要以鎖或不可分割操作保護,也要留意死結。

常見問題

執行緒會共用記憶體嗎?

會。同一個行程的執行緒共用該行程的程式碼、堆積與全域資料。各執行緒專屬擁有的只有堆疊與暫存器。

為什麼建立執行緒的成本比行程小?

新的行程需要專屬的位址空間,而執行緒使用行程的位址空間。執行緒的切換也不必改變位址空間,因此成本較小。

一個執行緒異常終止會怎麼樣?

因為執行緒共用記憶體,可能牽連整個行程。一個行程的異常終止,通常不會影響其他行程。

什麼時候應該使用行程而不是執行緒?

需要隔離與強健性時(瀏覽器的分頁、獨立的服務等),或想避免元件彼此破壞對方的記憶體時。

相關名詞的解說

環境切換
切換在CPU上執行的行程或執行緒。儲存並還原暫存器與程式計數器等狀態,切換行程時也會切換位址空間。
互斥鎖(Mutex)
同一時間只有一個執行緒能持有的鎖。無法取得時讓執行緒休眠並讓出 CPU,鎖被釋放時由作業系統喚醒,是一般常見的實作。
死結(Deadlock)
多個執行緒各自持有資源,並互相等待其他執行緒所持有的資源,使得誰都無法前進的狀態。可藉由全體統一取鎖順序來防止。

相關的比較