執行緒與並行

並行 vs 平行(concurrency vs parallelism)

想像廚房裡只有一位廚師同時應付三道菜:她攪一下湯,接著切菜,再去看烤箱,然後回頭攪湯。在任何一個瞬間她其實只在做一件事,但整個晚上下來,三道菜都有進展。這就是並行(concurrency)——把工作安排成讓好幾件任務同時「在進行中」並交錯推進,即使只有一個工人。再想像有三位廚師,一人一道菜,在同一刻一起煮。這就是平行(parallelism)——好幾件事真的同時發生。兩者感覺相似,卻不是同一個概念。

並行談的是「應付」很多任務:程式被寫成讓彼此獨立的活動可以被啟動、暫停、再恢復,並共用手上可用的工人。平行談的是「同時做」很多任務:在實體上同時執行它們,而這需要不只一個工人(不只一個 CPU 核心)。Rob Pike 有句俐落的說法:並行是一種「組織」程式的方式,平行是一種「執行」程式的方式。你可以在單一核心上有並行(一位廚師交錯做事),而只有當硬體擁有多個核心、能讓執行緒並排跑時,才會得到真正的平行。

這個區別對系統程式設計為何重要:一台單核機器跑十條執行緒是並行但非平行——作業系統在執行緒之間快速切換,讓每條都有進展,但任兩條指令都不會在同一瞬間執行。同樣的程式碼跑在八核機器上,就能讓八條執行緒真正平行。關鍵在於,我們將研究的那些危害(競爭條件、資料競爭)源自並行本身——源自任務共享狀態並交錯執行——就算在單核上也會咬人,因為切換可能發生在某個操作做到一半時。平行只是讓這些危害發生得更頻繁、更快。

下載十個檔案:在單核上用並行,程式同時啟動這十個,在每個等待網路時於它們之間切換,所以比一個一個來更早完成。在十核上用平行,十條執行緒能在同一瞬間各自處理一件耗 CPU 的工作。

並行是結構(任務交錯);平行是執行(任務真的同時)。

常見迷思:「並行」就代表「更快」。不一定——在單核上,並行帶來切換開銷,只有在任務有等待時才有幫助。而沒有平行的並行仍有全部的共享危害,因為切換可能落在某個操作中間。

又称
concurrent vs parallel並行與平行的區別