並行處理(concurrency)與平行處理(parallelism)在韓文和英文中看起來都很相似,因此經常被混用。
即使在 CPU 只有一個核心的年代,電腦也能一邊播放音樂、一邊編輯文件。這台實際上一次只能做一件事的機器,究竟如何「同時」處理多項工作?
如果能回答這個問題,就已經分清楚這兩個概念了。如果答不出來,本文正好會為你整理這個關鍵。
Swift Concurrency、GCD(Grand Central Dispatch)的 concurrent queue 等名稱也是如此。要正確理解它們,這項區分是基礎。
以下是重點總結。
- 並行處理:輪流推進多項工作並「同時處理」它們的結構問題。屬於邏輯概念
- 平行處理:多項工作在物理上於同一時間執行。屬於硬體問題
- 單核心也能進行並行處理。平行處理則需要多個核心
- 並行處理由程式碼結構建立,平行處理則是硬體利用該結構的結果
用一台咖啡機理解
想像一家只有一位咖啡師(1 個核心)的咖啡店。
店裡同時來了兩筆訂單。咖啡師在萃取 A 顧客的濃縮咖啡時加熱 B 顧客的牛奶,萃取完成後再做完 A 的飲品,接著回到 B。兩筆訂單都「同時進行中」,但無論截取哪個瞬間,咖啡師都只在做一件事。
這就是並行處理:把工作切成細小片段,輪流推進並一起處理多項工作。
再雇用一位咖啡師(2 個核心)後,兩筆訂單就真的能在同一時間製作。這就是平行處理。
重點是:即使只有一位咖啡師,「輪流處理訂單的運作方式」仍然成立;當咖啡師變成兩位時,同一套方式就擴展為物理上的同時執行。
換成電腦來看
單核心時代的多工處理,正是一家只有一位咖啡師的咖啡店。
作業系統以數十毫秒為單位,輪流將 CPU 分配給不同處理程序(時間切片)。因此在人的眼中,音樂播放與文件編輯就像是同時執行。
多核心出現後,平行處理也加入了。現在 4 個核心確實能在同一時間執行 4 個執行緒。
我們可以這樣整理兩者的關係。
- 只有平行處理、沒有並行處理:將互不相關的工作分別交給各核心執行
- 沒有平行處理的並行處理:單核心時間切片
- 並行處理+平行處理:現代運算的基礎,由多個核心分擔執行切分後的工作
Go 語言的創作者 Rob Pike 有一場著名演講,標題用一句話概括了這項區分。
「Concurrency is not parallelism(並行處理不是平行處理)。」
他將並行處理區分為「處理多項工作(dealing with)」,將平行處理區分為「執行多項工作(doing)」。
Swift Concurrency 這個名稱的意義
從這個角度來看,Apple 將 async/await 體系命名為 Swift「Concurrency」是很精確的。
async/await、Task、actor 都是用來表達「如何切分工作、在哪裡暫停,以及按照什麼順序恢復」的工具。換句話說,它們是設計並行處理結構的語言機制。
這個結構實際上會在幾個核心上平行執行,則由執行階段與系統排程器決定。開發者宣告結構(並行處理),平行執行則交給系統負責。
async let a = fetchProfile() // 宣告可「同時進行」的結構
async let b = fetchFeed()
let result = try await (a, b) // 是否以平行方式執行由系統決定
即使用 TaskGroup 建立 100 個工作,如果只有 8 個核心,同一時間最多也只能執行 8 個。其餘工作會輪流進行。在並行處理結構中,平行處理能發揮多少取決於硬體。
面試時用一句話說明
「並行處理是輪流推進多項工作並一起處理它們的邏輯結構;平行處理則是多項工作在物理上同一時間執行。因此,單核心可以進行並行處理,但無法進行平行處理。」
也可以先準備好延伸問題:「單核心多工如何實現?」(時間切片)、「並行處理程式碼是否總是平行執行?」(不是,由排程器決定)。
總結
- 並行處理是切分工作、輪流推進並一起處理多項工作的結構。它是邏輯層次的概念
- 平行處理是多項工作在物理上同一時間執行。它是硬體層次的概念
- 單核心也能進行並行處理(時間切片),但無法進行平行處理
- Rob Pike:並行處理是「處理」多項工作,平行處理是「執行」多項工作
- Swift Concurrency 是宣告並行處理結構的工具,實際的平行執行則由系統決定
- 咖啡機比喻:一位咖啡師輪流製作是並行處理,兩位咖啡師一起製作是平行處理

