原文連接:併發與並行的區別golang
如今咱們都說設計可並行、高併發的程序,並且咱們不少時候會在潛意識裏以爲本身對並行(Parallelism)和併發(Concurrency)的區別很清楚,但若是要明確的說出兩者的區別,又感受沒辦法給出一個很是清晰的描述。瀏覽器
那麼什麼是併發?什麼又是並行呢?並行的概念比較簡單,並行老是和執行(executions)相關,不少東西同時執行就是並行;而併發則是經過一些方式組織你的程序,讓它能夠分紅多個模塊去獨立的執行。並行必然是須要多核的,一個處理器是沒法並行的;但併發和處理器並無什麼必然聯繫,在一個處理器上面,咱們的程序也能夠是併發的。微信
舉個簡單的例子,華羅庚泡茶,必須有燒水、洗杯子、拿茶葉等步驟。如今咱們想盡快作完這件事,也就是「一共要處理不少事情」,有不少方法能夠實現併發,例如請多我的同時作,這就是並行。並行是實現併發的一種方式,但不是惟一的方式。咱們一我的也能夠實現併發,例如先燒水、而後不用等水燒開就去洗杯子,因此經過調整程序運行方式也能夠實現併發。網絡
若是你以爲以上的講解仍是太抽象了,下面經過一個小故事來說解,故事原型來自 Go 語言創始人之一 Rob Pike 的一篇演講。併發
故事的開始有一個需求:有一羣地鼠要把一堆廢棄的說明書用小推車推到火爐去燒燬。ide
剛開始只有一隻地鼠,使用一輛推車,將書裝到車上,運輸到火爐旁,將書卸到火爐。完成任務必然須要比較長的時間。高併發
此時若是再增長一隻地鼠,那也沒什麼用,由於一隻地鼠在幹活,另外一隻地鼠只能等待。(固然有人說兩隻地鼠輪流使用一輛推車,這樣可讓地鼠獲得休息,這樣它們幹活更快,也能夠提升效率。)post
再找一輛推車來,兩隻地鼠分別使用各自的推車,將書裝到車上,運輸到火爐旁,將書卸到火爐。這樣會提升運輸效率,但它們會在裝書和卸書時進行排隊,下降了效率。性能
這樣雖然比以前快了,但仍是有瓶頸的。由於書只有一堆,火爐也只有一個,因此咱們還必須經過消息來協調兩隻地鼠的行動。好吧,那咱們再把書分紅兩堆,再增長一個火爐。.net
這樣就比以前的效率高差很少一倍了。如今這個模型就是併發的,由於兩隻地鼠能夠獨立完成一件事了,這樣提升了運輸效率,並且在裝書和卸書時不會進行排隊,提升了裝卸的效率。但這個模型不必定是並行的,好比同一時刻可能只有一隻地鼠在幹活。
上面就是第一種併發模型,咱們還能夠設計更多的併發模型,繼續看漫畫。
此次找了 3 只地鼠,一隻負責把書裝到車上,一隻負責運輸,一隻負責把書卸到火爐焚燒。每隻地鼠作一個獨立的任務,固然三隻地鼠之間須要使用一些諸如消息通訊之類的手段進行協調。
裝書和燒書的兩隻地鼠都很輕鬆,負責運輸的這隻地鼠卻很累,系統出現了瓶頸。那咱們再找一隻地鼠來,專門負責運回空推車。
咱們在一個已有的設計(指三個地鼠的那個設計)中添加一個併發的步驟(第四隻地鼠)加強了系統的性能。這樣一來,兩隻地鼠去搞運輸,若是協調的好,理論狀況下工做效率將是一隻地鼠的 4 倍。
總共有 4 個併發的步驟:
能夠再增長一個分組,將這個併發模型並行化。
下面咱們再來看另一種併發模型。負責運輸的地鼠抱怨說運輸路程太長,那咱們就增長一箇中轉站。
而後再增長一個分組,將這個併發模型並行化,兩個分組並行執行。
能夠把上面的併發模型再改進一下。增長中轉站的同時,再增長兩隻地鼠,一隻負責將從書堆運過來的書卸到中轉站,另外一隻負責將書從中轉站裝到推車裏,再讓後面的地鼠運輸到火爐旁。
而後再增長一個分組,將這個併發模型並行化。
漫畫到這裏就結束了,總共介紹了三種併發模型,每種模型均可以很容易地並行化。能夠看到上面的併發模型每改進一次,其實就是將任務拆的更細了,一旦分解了問題,併發就天然而然產生了,每一個人只專一於一個任務。
回到程序中,書就表明着數據,地鼠就是 CPU,而車可能就是序列化、反序列化、網絡等設施,火爐就是代理、瀏覽器或其餘的消費者。而上面的併發模型就是一個可擴展的 Web Service。
該演講題目爲《Concurrency is not Parallelism》
,原文連接:
參考連接
掃一掃下面的二維碼關注微信公衆號,在公衆號中回覆◉加羣◉便可加入咱們的雲原生交流羣,和孫宏亮、張館長、陽明等大佬一塊兒探討雲原生技術