很多人不是特別明白並發編程和並行編程的區別所在,有很多人很容易搞混淆,覺得二者近似相等,本文將用幾個淺顯易懂的例子,來說明一下什么是並發和並行。
1、任務與多任務
關於什么是進程,什么是線程,這里不打算多說,關於每一種開發語言的多線程處理技術語法上有所區別,原理很多類似,可以查閱相關的參考書。什么是任務呢?其實很簡單,在我們生活中,比如我今天要學一首歌,要在操場上散步1000米,然后還要向老師電話匯報研究成果,這是今天的三個任務。在編程語言中,實現某一個任務的一般單元就是“函數”。
2、順序執行
上面三個任務,如果在一般的單線程執行的程序里面,分別定義三個函數,然后依次順序執行,即執行完第一個在執行第二個,然后執行第三個,即我先把一首歌學會,然后在操場上散步1000米,然后再給老師匯報,這樣做效率低下。
我們可以有一個更加高效的辦事方法,我在散步的時候,順便打電話給老說匯報一下今天的成果,然后邊散步邊聽歌,便跟着學,這樣效果就高很多,這里的是“並行執行”。
3、並發和並行的一些理解——concurrency and parallellism
並發和並行都是完成多任務更加有效率的方式,但還是有一些區別的,並發(concurrency),並行(parallellism),可見他們的確是有區別的。下面通過一些具體的例子進行說明。
例子一:
假設一個有三個學生需要輔導作業,幫每個學生輔導完作業是一個任務
順序執行:老師甲先幫學生A輔導,輔導完之后再取給B輔導,最后再去給C輔導,效率低下 ,很久才完成三個任務
並發:老師甲先給學生A去講思路,A聽懂了自己書寫過程並且檢查,而甲老師在這期間直接去給B講思路,講完思路再去給C講思路,讓B自己整理步驟。這樣老師就沒有空着,一直在做事情,很快就完成了三個任務。與順序執行不同的是,順序執行,老師講完思路之后學生在寫步驟,這在這期間,老師是完全空着的,沒做事的,所以效率低下。
並行:直接讓三個老師甲、乙、丙三個老師“同時”給三個學生輔導作業,也完成的很快。
例子二:
順序執行:你吃飯吃到一半,電話來了,你一直到吃完了以后才去接,這就說明你不支持並發也不支持並行。
並發:你吃飯吃到一半,電話來了,你停了下來接了電話,接完后繼續吃飯,這說明你支持並發。
並行:你吃飯吃到一半,電話來了,你一邊打電話一邊吃飯,這說明你支持並行。此處注意理解:是同時吃,同時說,要真嚴格的說的話,需要2張嘴才是並行。
4、理解:
(1)並行是指兩個或者多個事件在同一時刻發生;而並發是指兩個或多個事件在同一時間間隔發生。
(2)並行是在不同實體上的多個事件,並發是在同一實體上的多個事件。
(3)在一台處理器上“同時”(這個同時實際上市交替“”)處理多個任務,在多台處理器上同時處理多個任務。如hadoop分布式集群
普通解釋:
並發:交替做不同事情的能力
並行:同時做不同事情的能力
專業術語:
並發:不同的代碼塊交替執行
並行:不同的代碼塊同時執行
5、總結:
如果某個系統支持兩個或者多個動作(Action)同時存在,那么這個系統就是一個並發系統。
如果某個系統支持兩個或者多個動作同時執行,那么這個系統就是一個並行系統。
並發系統與並行系統這兩個定義之間的關鍵差異在於“存在”這個詞。
在並發程序中可以同時擁有兩個或者多個線程。這意味着,如果程序在單核處理器上運行,那么這兩個線程將交替地換入或者換出內存。這些線程是同時“存在”的——每個線程都處於執行過程中的某個狀態。
如果程序能夠並行執行,那么就一定是運行在多核處理器上。此時,程序中的每個線程都將分配到一個獨立的處理器核上,因此可以同時運行。
我相信你已經能夠得出結論——“並行”概念是“並發”概念的一個子集。也就是說,你可以編寫一個擁有多個線程或者進程的並發程序,但如果沒有多核處理器來執行這個程序,那么就不能以並行方式來運行代碼。因此,凡是在求解單個問題時涉及多個執行流程的編程模式或者執行行為,都屬於並發編程的范疇。
並發就是指代碼邏輯上可以並行,有並行的潛力,但是不一定當前是真的以物理並行的方式運行。並發指的是代碼的性質,並行指的是物理運行狀態。
顧名思義,並發強調的是一起出發,並行強調的是一起執行。並發的反義是順序,並行的反義是串行。並發並行並不是互斥概念,只不過並發強調任務的抽象調度,並行強調任務的實際執行。