OK,如果你還在為并發(concurrency)和并行(parallelism)這兩個詞的區別而感到困擾,那么這篇文章就是寫給你看的。不論中文圈還是英文圈,即使已經有數不清的文章在討論并行vs并發,卻極少有能講清楚的。讓一個講不清楚的人來解釋,比不解釋更可怕。
回歸正題,Erlang 之父 Joe Armstrong 用一張5歲小孩都能看懂的圖解釋了并發與并行的區別
并發是兩個隊列交替使用一臺咖啡機,并行是兩個隊列同時使用兩臺咖啡機。
我們來具體探究一下并行與并發的概念。
并行(parallelism)
這個概念很好理解。所謂并行,就是同時執行的意思。判斷程序是否處于并行的狀態,就看同一時刻是否有超過一個“工作單位”在運行就好了。所以,單線程永遠無法達到并行狀態。要達到并行狀態,最簡單的就是利用多線程和多進程。
并發(concurrency)
要理解“并發”這個概念,必須得清楚,并發指的是程序的“結構”。當我們說這個程序是并發的,實際上,這句話應當表述成“這個程序采用了支持并發的設計”。好,既然并發指的是人為設計的結構,那么怎樣的程序結構才叫做支持并發的設計?正確的并發設計的標準是:使多個操作可以在重疊的時間段內進行(two tasks can start, run, and complete in overlapping time periods)。
并行指物理上同時執行,并發指能夠讓多個任務在邏輯上交織執行的程序設計
我的理解:
可以一起出發的并發(concurrent)相對的是不可以一起出發的順序(sequential)
順序:上一個開始執行的任務完成后,當前任務才能開始執行
并發:無論上一個開始執行的任務是否完成,當前任務都可以開始執行
與可以一起執行的并行(parallel)相對的是不可以一起執行的串行(serial):
串行:有一個任務執行單元,從物理上就只能一個任務、一個任務地執行
并行:有多個任務執行單元,從物理上就可以多個任務一起執行
我們用大白話的方式就是:
你吃飯吃到一半,電話來了,你一直到吃完了以后才去接,這就說明你不支持并發也不支持并行。
你吃飯吃到一半,電話來了,你停了下來接了電話,接完后繼續吃飯,這說明你支持并發。
你吃飯吃到一半,電話來了,你一邊打電話一邊吃飯,這說明你支持并行。
并發的關鍵是你有處理多個任務的能力,不一定要同時。
并行的關鍵是你有同時處理多個任務的能力。
所以我認為它們最關鍵的點就是:是否是『同時』。
綜上,并發與并行并不是互斥的概念,并發設計讓并發執行成為可能,而并行是并發執行的一種模式。