language agnostic - concurrent - 並發性和並行性之間的區別是什麼?




concurrent computing中文 (20)

並發性和並行性之間的區別是什麼?

例子表示讚賞。


“並發”是指有多件事正在進行

“並行性”是指同時發生的事情同時發生。

沒有並行性的並發例子:

  • 單個核心上的多個線程。
  • Win32消息隊列中的多條消息。
  • MARS連接上的多個SqlDataReader
  • 瀏覽器選項卡中的多個JavaScript promises

但是請注意,並發性和並行性之間的差異通常是一個角度問題。 從執行代碼的(可觀察的效果)的角度來看,上面的例子是不平行的。 但是,即使在一個核心內部也存在指令級並行性。 有些硬件可以與CPU並行處理,然後在完成時中斷CPU。 當窗口過程或事件處理程序正在執行時,GPU可能正在繪製屏幕。 數據庫管理系統可能會在下一個查詢中遍歷B樹,而您仍然在獲取前一個查詢的結果。 當你的Promise.resolve()被執行時,瀏覽器可以做佈局或網絡。 等等...

所以你去了。 世界一如既往地混亂;)


並發可以涉及任務同時運行或不運行(它們確實可以在單獨的處理器/內核中運行,但它們也可以運行在“滴答”中)。 重要的是並發性總是指做一件更大的任務 。 所以基本上它是一些計算的一部分。 你必須明白你可以同時做什麼,不要做什麼以及如何同步。

並行性意味著你只是在同時做一些事情。 他們不需要成為解決一個問題的一部分。 例如,你的線程可以解決每個問題。 當然,同步的東西也適用,但從不同的角度。


並發性是指兩個或更多任務可以在重疊時間段內啟動,運行並完成。 這並不一定意味著他們都會在同一時刻跑步。 例如,在單核機器上進行多任務處理

並行是當任務實際上同時運行時,例如,在多核處理器上。

引用Sun的多線程編程指南

  • 並發性:至少有兩個線程正在進步時存在的條件。 一種更普遍的並行性形式,可以包括時間分割作為虛擬並行的一種形式。

  • 並行性:至少有兩個線程同時執行時出現的一種情況。


並發性是獨立執行的進程的組成,而並行則是同時執行(可能相關)的計算。

並發是一次處理很多事情。 並行是一次做很多事情。


並行 -意味著應用程序將其任務分解為可以並行處理的較小子任務,例如在同一時間在多個CPU上進行處理。

並發 -意味著應用程序在同時(同時)在多個任務上取得進展。 那麼,如果計算機只有一個CPU,則應用程序可能無法在同一時間完成多個任務,但是應用程序內一次正在處理多個任務。 它在開始下一個任務之前並不完全完成一項任務。

重要的是要注意並行性意味著並發性,但並發並不能保證並行性。 基本上,並發是關於結構,而並行則是關於執行。


並行性:具有多個線程執行相似的任務,這些任務在數據和資源方面彼此獨立,他們需要這樣做。 例如:Google抓取工具可以產生數千個線程,每個線程都可以獨立執行任務。

並發性:當共享數據,線程間共享資源時,會出現並發性。 在一個事務處理系統中,這意味著你必須使用諸如鎖,信號等一些技術來同步代碼的關鍵部分。


並發簡單意味著多個任務正在運行(不必並行)。 例如,我們有3個任務,然後在任何時刻:不止一個可能正在運行,或者所有可能同時運行。

平行性意味著它們在字面上並行運行。 所以在這種情況下,所有三個必須同時運行。


並發編程涉及似乎重疊的操作,主要關注由於非確定性控制流而產生的複雜性。 與並發程序相關的定量成本通常都是吞吐量和延遲。 並發程序往往是IO界限,但並非總是如此,例如並發垃圾收集器完全在CPU上。 並發程序的教學例子是一個網絡爬蟲。 該程序啟動對網頁的請求,並在下載結果可用時同時接受響應,並累積一組已經訪問過的頁面。 控制流是非確定性的,因為每次程序運行時,響應不一定以相同的順序接收。 這個特性會使調試並發程序變得非常困難。 某些應用程序基本上是並發的,例如Web服務器必須同時處理客戶端連接。 Erlang也許是高度並發編程中最有前途的語言。

並行編程涉及為了提高吞吐量的特定目標而重疊的操作。 通過使控制流確定性避免了並發編程的困難。 通常情況下,程序產生並行運行的子任務集合,並且只有每個子任務完成後,父任務才會繼續。 這使並行程序更容易調試。 並行編程的難點在於關於粒度和通信等問題的性能優化。 後者在多核環境中仍然是一個問題,因為將數據從一個緩存傳輸到另一個緩存會產生相當大的成本。 密集矩陣乘法是並行編程的教學實例,它可以通過使用Straasen的分治算法並行地攻擊子問題來有效解決。 Cilk可能是在共享內存計算機(包括多核)上進行高性能並行編程的最有前途的語言。


來自jenkov java並發教程

術語並發性和並行性通常用於多線程程序。 但是並發性和並行性究竟意味著什麼,它們是相同的術語還是什麼?

最簡潔的答案是不”。 它們並不是相同的術語,儘管它們表面上看起來很相似。 這也花了我一些時間來最終找到並理解並發和並行之間的區別。 因此我決定在這個Java並發教程中添加一個關於並發性和並行性的文本。 並發

並發意味著應用程序在同時(同時)在多個任務上取得進展。 那麼,如果計算機只有一個CPU,則應用程序可能無法在同一時間完成多個任務,但是應用程序內一次正在處理多個任務。 它在開始下一個任務之前並不完全完成一項任務。 排比

並行性意味著應用程序將其任務分解為可以並行處理的較小子任務,例如在同一時間在多個CPU上進行處理。 並發性與並行性的細節

如您所見,並發與應用程序處理多個任務的方式有關。 應用程序可以同時處理一個任務(按順序)或同時處理多個任務(並發)。

另一方面,並行性與應用程序處理每個單獨任務的方式有關。 應用程序可以從頭到尾連續處理任務,也可以將任務分解為可以並行完成的子任務。

正如你所看到的,一個應用程序可以是並發的,但不是並行的。 這意味著它可以同時處理多個任務,但這些任務不會分解為子任務。

應用程序也可以是並行的,但不是並發的。 這意味著應用程序一次只能處理一個任務,並且該任務被分解為可以並行處理的子任務。

另外,應用程序既不能並行也不能並行。 這意味著它一次只能在一個任務上工作,並且任務永遠不會分解為並行執行的子任務。

最後,一個應用程序也可以是並行的,也可以是並行的,因為它既可以同時處理多個任務,也可以將每個任務分解為子任務以便並行執行。 但是,在這種情況下,並發性和並行性的一些好處可能會丟失,因為計算機中的CPU已經保持合理忙於並發或併行。 將它結合起來可能只會導致很小的性能增益甚至性能損失。 確保在盲目地採用並行並行模型之前進行分析和測量。


來自此源的說明對我有幫助:

並發性與應用程序處理多個任務的方式有關。 應用程序可以同時處理一個任務(按順序)或同時處理多個任務(並發)。

另一方面,並行性與應用程序處理每個單獨任務的方式有關。 應用程序可以從頭到尾連續處理任務,也可以將任務分解為可以並行完成的子任務。

正如你所看到的,一個應用程序可以是並發的,但不是並行的。 這意味著它可以同時處理多個任務,但這些任務不會分解為子任務。

應用程序也可以是並行的,但不是並發的。 這意味著應用程序一次只能處理一個任務,並且該任務被分解為可以並行處理的子任務。

另外,應用程序既不能並行也不能並行。 這意味著它一次只能在一個任務上工作,並且任務永遠不會分解為並行執行的子任務。

最後,一個應用程序也可以是並行的,也可以是並行的,因為它既可以同時處理多個任務,也可以將每個任務分解為子任務以便並行執行。 但是,在這種情況下,並發性和並行性的一些好處可能會丟失,因為計算機中的CPU已經保持合理忙於並發或併行。 將它結合起來可能只會導致很小的性能增益甚至性能損失。


具有共享資源潛力的多個執行流程

例如:兩個線程競爭一個I / O端口。

平等主義:以多個相似的塊分裂問題。

例如:通過在文件的每一半上運行兩個進程來解析一個大文件。


在我看來,最簡單最優雅的理解方式就是這樣。 並發性允許交錯執行,因此可以給出並行性的錯覺 。 這意味著一個並發系統可以運行您的Youtube視頻,例如您在Word中編寫文檔。 底層操作系統是一個並發系統,可以使這些任務交錯執行。 由於計算機如此迅速地執行指令,這使得一次執行兩件事情的外觀。

並行是當這些事情真的平行時。 在上面的示例中,您可能會發現視頻處理代碼正在單個核心上執行,而Word應用程序正在另一個核心上運行。 請注意,這意味著並發程序也可以並行執行! 使用線程和進程構建應用程序可以讓程序利用底層硬件並且可能並行完成。

為什麼不把所有東西都平行呢? 其中一個原因是因為並發性是構建程序的一種方式,並且是一種促進關注點分離的設計決策,而並行性通常以性能名義使用。 另一個原因是有些東西基本上不能完全並行地完成。 一個例子就是在隊列的後面增加兩件事 - 你不能同時插入兩個東西。 一些東西必須先放在後面,否則你會弄亂隊列。 雖然我們可以交錯執行(因此我們可以獲得併發隊列),但不能使它並行。

希望這可以幫助!


增加別人的話:

並發就像讓一個玩雜耍的人玩轉很多球。 無論看起來如何,這個玩雜耍的人每次只能每手抓一個球。 平行主義讓多個玩雜耍的人同時玩弄球。


太好了,讓我看看我的理解。 假設有3個孩子叫:A,B,C。A和B說話,C聽。 對於A和B,它們是平行的:A:我是A. B:我是B.

但對於C,他的大腦必須採取並發的過程來聽A和B,它可能是:我是IA和B.


想像一下,通過觀看視頻教程來學習一種新的編程語言。 您需要暫停視頻,應用代碼中所說的內容,然後繼續觀看。 這是並發性。

現在你是一名專業程序員。 編碼時,你喜歡聽冷靜的音樂。 這是並行性。

請享用。


我喜歡Rob Pike的談話:並發不是平行(更好!) (slides) (talk)

Rob通常會談論Go,通常以直觀和直觀的解釋來解決並發VS並行的問題! 這裡是一個簡短的總結:

任務:讓我們刻錄一堆陳舊的語言手冊! 一次一個!

並發性:有很多並發的任務分解! 一個例子:

並行性:如果至少有兩個Gopher在同一時間工作,則以前的配置並行發生。


我將提供一個與這裡的一些流行答案有點矛盾的答案。 在我看來,並發是一個包含並行性的通用術語。 並發適用於任何不同的任務或工作單元在時間上重疊的情況。 並行性更具體地適用於在同一物理時間評估/執行不同工作單元的情況。 並行性的存在正在加速可以從多種物理計算資源中受益的軟件。 適合併發的另一個主要概念是交互性。 交互性適用於任務重疊可從外部世界觀察到的情況。 交互性的存在使軟件能夠響應用戶,網絡對等設備,硬件外設等真實世界的實體。

並行性和交互性幾乎完全是並發性的獨立維度。 對於一個特定的項目開發人員可能會關心或者兩者兼得,或者都不關心。 他們傾向於混淆,尤其是因為線程的可憎性為兩者都提供了相當方便的原始語言。

關於並行性的更多細節

並行性存在於非常小的範圍內(例如處理器中的指令級並行性),中等規模(例如多核處理器)和大規模(例如高性能計算集群)。 由於多核處理器的增長,近年來軟件開發人員面臨更多線程級並行性的壓力增加。 並行性與依賴概念密切相關 。 依賴性限制了並行性的實現程度; 如果兩個任務依賴於另一個(忽略猜測),則兩個任務不能並行執行。

程序員使用很多模式和框架來表達並行性:流水線,任務池,數據結構上的集合操作(​​“並行陣列”)。

關於交互性的更多細節

進行交互的最基本和常見的方式是事件(即事件循環和處理程序/回調)。 對於簡單的任務來說,事件很棒 試圖用事件做更複雜的任務進入堆棧翻錄(aka callback hell; aka control inversion)。 當你厭倦事件時,你可以嘗試更多奇特的東西,比如生成器,協程(又名Async / Await)或合作線程。

對於可靠軟件的喜愛,如果你想要的是互動性,請不要使用線程。

Curmudgeonliness

我不喜歡Rob Pike的“並發不是並行,更好”的口號。 並發性既不比並行性好也不比差。 並發性包括交互性,這種交互性無法以更好/更差的方式與並行性進行比較。 這就像說“控制流程比數據更好”。


我非常喜歡Paul Butcher對這個問題的answer (他是七週內七個並發模型的作者):

雖然他們經常困惑,但並行和並發是不同的事情。 並發是問題領域的一個方面 - 您的代碼需要處理多個同時(或幾乎同時)的事件相反,並行性是解決方案領域的一個方面,您希望通過並行處理問題的不同部分讓程序更快運行。 一些方法適用於並發性,一些適用於並行性,另一些適用於兩者。 了解你所面對的並選擇正確的工具。


派克關於“並發”的概念是有意設計和實施的決定。 並發能力的程序設計可能會或可能不會表現出行為“並行性”; 它取決於運行時環境。

您不希望並行性不是為並發而設計的。 :-)但是,就相關因素(功耗,性能等)而言,這是一個淨增益,您需要一個最大並發設計,以便主機系統在可能的情況下並行執行它的執行。

派克的Go編程語言將這一點說明了極端:他的函數是所有可以並發正確運行的線程,即調用一個函數總是會創建一個與調用者並行運行的線程(如果系統有能力的話)。 擁有數百甚至數千線程的應用程序在他的世界中是完全普通的。 (我不是專家,這只是我的看法。)


簡單的例子:

同時發生的情況是:“兩個隊列訪問一台ATM機”

並行是:“兩個隊列和兩台ATM機”





parallel-processing