1. 程式人生 > >像鳥一樣思考更好的並行編程

像鳥一樣思考更好的並行編程

Java 並發編程 高並發 高可用

介紹

編寫一個應用程序並行運行很困難,對吧?我的意思是,它一定很難,否則我們會看到各處的並行程序。我們所看到的都是平滑的並行應用程序,可以毫不費力地使用每個可用的核心。相反,多線程應用程序是例外而不是規則。

編寫並行程序似乎有兩個主要障礙:

  • 學習您選擇的語言提供的並行編程結構和/或約定

  • 可視化您的並行程序的功能

第一項似乎很明顯:休息一下,學習所選編程語言的並行功能,然後離開你 - 並行程序將從你的編譯器中跳出。除非那天下午通常會變成幾天,這通常會變成一段更長的時間,而你選擇的語言的平行特征的含義,並發癥和後果則會被馴服。

第二項似乎應該提到幾乎是微不足道的。畢竟,開發一個新計劃的第一步是想象它的主要組成部分以及它們將如何運作。除了我們通常將我們的新程序可視化為順序代碼組件,以便我們稍後(如果必須的話)將某些並行的東西“栓上”。正是這種思維框架使我們從一開始就走上了錯誤的道路。

相反,我們需要考慮像鳥這樣的程序。或者說,成群的鳥兒。

背景

Avian計算項目是通過改進我們對並行編程的思考來改善並行編程的一種方式。Avian Computing鼓勵我們將並行程序可視化為一群鳥,每個鳥(線程)獨立並異步地執行操作,但它們同時作為一群來完成程序的目標。

我們都熟悉鳥類:它們被孵化出來,四處飛翔尋找食物,產卵並孵化自己的鳥類,然後死亡。Avian Computing將這些基本的鳥類行為轉化為開發人員可以利用的編碼框架來快速開發工作並行程序的原型。從構建這個工作原型獲得的知識深度和見解可以簡化最終軟件產品的開發。

Avian計算的實現

並發資源管理器(ConcX)是用Java編寫的Avian Computing的概念的免費開源實現。ConcX為用戶提供了一個可以創建和配置新鳥的GUI屏幕。配置完成後,可以啟動小鳥並在進度條上監控其活動。配置好的鳥群可以保存為一個“群”,可以根據需要重新加載和運行。

技術分享圖片

一旦孵化(開始),每只鳥(線)遵循標準生命周期; 它尋找食物,消化找到的任何匹配的食物,儲存任何產生的食物,然後小睡一會兒。在配置的耐力時限內找不到食物的鳥類將因饑餓而死亡。活得太久的鳥會死於老年。成功吃足以滿足可配置設置的鳥類將復制(重復自己)。這個標準生命周期允許使用簡單自然的詞匯來處理線程管理的復雜性,這些詞匯幾乎可以直觀地理解。

ConcX依賴於Linda協調語言來從共享虛擬關聯存儲器(稱為元組空間)中放置和檢索對象。Linda起源於1986年,由Sudhir Ahuja,David Gelernter和Nicholas Carriero創作。Linda是幾個主要產品的基礎,包括Sun的JavaSpaces,IBM的TSpaces等等。

ConcX使用稱為TupleTree的Linda元組空間的簡化版本。鳥類通常配置為在TupleTree中食用和儲存食物豆莢。例如,RedPod可以被配置為吃RedPods的任何鳥食用,並且將被所有其他鳥類忽略。在消化它的食物莢後,一只鳥會將加工後的物體存放回TupleTree,通常作為不同種類的食物莢(例如BluePod),以供不同的鳥類食用。

Linda(及其派生,TupleTree)提供了一個安全,簡單和強大的消息傳遞機制。在ConcX中,TupleTree允許在用戶編寫的代碼中沒有任何特殊的代碼或註意事項的情況下共享對象,因為TupleTree同步(鎖定或以其他方式提供獨占訪問)所有與其底層數據存儲交互的方法。

使TupleTree對所有鎖定負責,確保鳥兒接收的任何食物吊艙(物體)完全由該鳥類擁有,而不會使用鎖定和互斥等使用戶代碼混亂。這意味著任何接收到食物吊艙的鳥都是免費的在沒有來自任何其他鳥類的爭用或幹擾的情況下對該食品盒進行任何改變。在做出任何必要的改變之後,該鳥可以將其食物吊艙放回TupleTree,在那裏不同種類的鳥會吃它並進行改變。

平行思維的簡單範例

ConcX提供的Addx場景是Avian計算概念如何生成更簡單的並行代碼的直接示例。Addx場景的目標是通過對每個值執行一系列數學運算來處理一系列值,直到計算出最終值並保存為止。數學運算必須始終以相同的順序執行。

在標準的順序編碼中,我們將通過獲取下一個值,執行第一個數學運算,然後第二個數學運算,然後第三個數學運算等開始可視化一個循環,直到計算出最終值為止,該值為保存,然後循環重復。看起來相對簡單,並且運行速度盡可能快。其最大吞吐量取決於執行單線程的一個處理器的速度。

為了更快速地處理更多的值,需要使用多個處理器,這就是棘手的問題。正常的解決方案是創建一個線程池,每個線程執行上述的順序代碼。但是這會使處理復雜化,因為並行代碼必須 確保輸入值僅由一個線程處理,並且不會跳過輸入值,同時確保不會發生死鎖和活鎖。很難想象線程可能會互相幹擾的所有可能的方式 - 在客戶的站點上展示了多次新的令人驚訝的失敗模式。更不用說必須為每個運行時環境(筆記本電腦vs大型機等)預先配置和編譯多個版本的應用程序。

Addx(Avian)解決方案配置了一個任意數量的鳥群,每只鳥只吃一種食物,並且在將其作為不同類型的食物放回之前,只對該食物執行一次數學運算。通過適當配置食物和儲存的食物,保證數學操作的正確順序。例如,Bird1吃Food1,對其執行數學運算,並將其存儲為Food2。Bird2吃Food2,對它進行數學運算,並將其作為Food3存儲。Bird3吃Food3,等等。這也可以更簡潔地表達為:

食物1 - > Bird1 - > FOOD2 - > BIRD2 - > Food3 - > Bird3。。。.Foodn - > Birdn。

以下簡化圖說明了Avian並行性。

  • 在下面的生命周期1中,所有五只鳥在大約同一時間開始飛行,但只有Add1Bird找到任何食物。它對該值執行操作,然後將其作為只有Add2Bird吃的食物放回到TupleTree中。

  • 在生命周期2中,Add1Bird和Add2Bird都可以找到食物,以便他們都執行各自的操作,然後將其食物存儲回TupleTree。

  • 在生命周期3中,Add1Bird,Add2Bird和Add3Bird都可以找到它們的食物種類,處理它們並將它們放回到TupleTree中。

技術分享圖片

大約第五個循環通過它們的生命周期(找到食物,消化它,儲存它和午睡),所有五只鳥同時從TupleTree進食,處理它們的莢,並將它們更新的莢儲存在樹中。上面只畫了5只鳥,但很容易想象將這個圖放大到包括20只或50只或100只鳥,它們都將同時運行(飛行),所有這些都遵循相同的簡單和自然的模式。就像真正的鳥類一樣,如果任何鳥類尋找食物並且沒有找到它,它就會等待一會兒,然後再次嘗試。

重要提示:如圖所示這鳥不步調一致操作的簡化圖。每只小鳥以其自己的個體速率生活,因為每次小睡時,它會隨機選擇一段時間(在可配置的範圍內)。這意味著隨機短時間小睡的小鳥會比隨機長時間小睡的小鳥更快地完成其生命周期。隨著時間的推移,午睡的時間長短會趨於平緩,所以一段時間以後會很慢。在現實生活中,Add5Bird(或任何其他鳥)開始吃之前可能需要3或10或15個周期。

配置鳥類

ConcX提供GUI屏幕來添加,配置和啟動鳥類。GUI屏幕還可以在鳥兒飛行時提供動態的實時狀態更新。以下屏幕截圖顯示了運行Addx場景的五只小鳥。屏幕右側的進度條實時顯示每只鳥的成功。每只鳥的進度條越長,鳥成功吃的次數就越多。

技術分享圖片

由於每只鳥都有用戶可選擇的食物類型,因此重新排列數學運算的順序很簡單。只需更改選定的食物並重新運行即可。如果任何鳥的配置不合適,它將無法找到食物,其進度條也不會增長。

“食物供應”選項卡包含食物容器進度條,可以實時動態顯示可用食物容器的數量。當運行結束時,TupleTree選項卡顯示其包含的食物莢的時間戳列表以及每個食物莢內容的簡要摘要以及每個食物莢和哪些鳥執行的交易。

上述功能都集成到並發資源管理器中,允許您交互式地探索和開發並行程序。一旦你了解了如何將程序分解為可以並行運行的子步驟,則可以使用所選擇的編程語言對應用程序進行編碼。

使用代碼

下面顯示了Add3Bird的完整Java代碼。它只有43行,幾乎一半(19)的行可以是註釋或空白(用於視覺分離的空白或單個花括號)。Add3Bird所需的唯一代碼是afterDigestion方法的重寫,它所做的只是將3添加到它找到的任何非空食品盒中。查找窗體並將其存儲回樹中都由BasicBird框架處理,使開發人員的工作變得更輕松。

技術分享圖片

對於上面的代碼最重要的是,在這段代碼中沒有鎖定或同步或互斥,因為它全部由TupleTree和ConcX框架處理。所有的多線程並行代碼都在後臺進行管理,因此用戶可以專註於如何將主要任務劃分為鳥類可以並行處理原子的小尺寸碎片。

雖然上述任務可能看起來過於簡單,但它實際上只是更復雜場景的模板。例如,如果Add1Bird被一只抓住10毫秒聲音的鳥取代並且Add2Bird被替換為對其執行快速傅裏葉變換的鳥並且Add3Bird被替換為試圖將所得輸出與其他先前處理的結果等。如果第二只鳥跟不上第一只鳥,而不是試圖修改它以加快運行速度(並且可能引入錯誤),那麽首選的Avian解決方案就是添加另一個實例(或另外10個實例)第二只鳥。

興趣點

Avian Computing的開發旨在鼓勵用戶基於天生平行的模型(例如鳥群)來形象化他們的並行程序。蜜蜂蜂群,魚群或馬群也可以作為模型,因為它們都包含多個獨立運行並且異步運行的角色,同時也可以一起工作。

ConcX是由開發人員/實驗者共同創建的。這是一個交互式環境,允許用戶啟動和停止鳥類的各種組合和配置。雖然每只鳥的飛行都有一個不斷更新的進度條,以顯示它的成功程度和可用的食物供應量。飛行結束後,可以檢查雞群的結果以及每只雞的事件歷史記錄。

Avian Computing和ConcX實現的概念旨在成為培訓輪子,幫助我們的單線程思維思考並討論並行程序。

要詳細了解Avian Computing的基本概念以及為什麽我們需要幫助來思考並行程序,請訪問Avian Computing網站。如果您準備嘗試一下,可以從Avian網站或SourceForge下載ConcX-2.x.zip(jar文件,lib文件和flock文件)。請務必同時下載“Avian Computing入門指南”用戶指南,因為它包含安裝信息以及大約十幾種並行方案,例如並行計算Pi,用餐哲學家Probelm,BarberShop場景等。

針對上面的技術我特意整理了一下,有很多技術不是靠幾句話能講清楚,所以幹脆找朋友錄制了一些視
頻,很多問題其實答案很簡單,但是背後的思考和邏輯不簡單,要做到知其然還要知其所以然。如果想
學習Java工程化、高性能及分布式、深入淺出。微服務、Spring,MyBatis,Netty源碼分析的朋友可以
加我的Java進階群:744642380,群裏有阿裏大牛直播講解技術,以及Java大型互聯網技術的視頻免費分
享給大家


像鳥一樣思考更好的並行編程