在.NET應用程序中進行Erlang風格的並行編程(第1部分)——CCR

在.NET應用程序中進行Erlang風格的並行編程(第1部分)——CCR

作者 Jonathan Allen譯者 趙劼

【整理】:Ackarlix

發佈於 2008年12月22日 上午6時37分

 

Erlang能夠用來編寫高度可伸縮的並行應用程序,其中經常會出現數以百萬計的輕量級組件,這種類似於線程的組件被稱之爲actor。不幸的是,這往往需要您使用Erlang這種相對神祕的編程語言重寫所有代碼。不過我們也有其他選擇,例如使用名不見經傳的CCR平臺來進行開發,該平臺由.NET機器人部門開發。

作爲一種基於Actor的語言,Erlang通過Actor模型能夠實現高度併發性。在這個模型中,最基礎的並行單元不是線程或纖程(fiber) ,而是一種更爲輕量級的東西。作爲Erlang中的“進程”,每個並行單元在一個32位系統中只佔用大約1200字節的基礎資源。與此相對的是,Windows操作系統中的每個線程默認會在棧上分配1MB空間,此外還需要額外的空間來作爲簿記(Bookkeeping)和線程本地存儲。由於非常輕量,一個應用程序輕鬆支持百萬計的進程進行併發處理。

在任一時刻,大部分的進程處於空閒狀態。當一個進程接受到了一條消息,運行平臺將爲其分配一個線程來應答這條消息。一條應答可能會創建一個新的進程,向其他進程發送消息,或者改變自身狀態。一旦消息被處理之後,這個進程將會死亡,或者繼續等待下一條消息。

消息處理系統實現了高端的並行性和高性能。每條消息都爲異步發送,使得進程之間相互高度獨立。平臺能夠通過消息來得知應該喚醒哪個進程。由於每個進程都能被任意的線程來處理,因此就可以大大減少耗費相對昂貴的上下文切換操作。

.NET中使用CCR,也就是Coordination Currency Runtime作爲Erlang模型的迴應。CCR原本面向機器人平臺,正在設法擴展更廣闊的市場。Siemens Automation的一個開發人員只花了幾年時間就將CCR集成進他們目前的Blackboard代碼庫。Blackboard是一個使用AI代理和傳送帶將信件以10米每秒的速度進行分發的系統,包含數百萬行遺留代碼。Tyco是個負責從小商店到白宮的各種事情的安全公司,也在數週內與CCR進行了集成。這些並非是推銷性質的案例,Siemens和Tyco沒有藉助微軟的幫助就完成了大量的工作。

CCR的核心是一個名爲“端口(port)”的API級別的概念。有別於以往調用類方法的方式,開發人員使用向端口發送消息來執行操作。附加在端口上的調控器會讀取消息,如果它們符合特定的標準,就會將消息成批地交給任務進行處理。任務會被放進分發隊列中,稍後就會被線程池執行。

調控器形成了調度單元的基礎。它們可以只是個簡單地單個端口的接收器,或多個端口的聯合/選擇接收器。如果需要更復雜的邏輯,它們甚至可以進行各種組合。不過它們的最終目的只有一個,那就是在收到數據時喚醒並執行一系列代碼。

CCR的真正威力來自C#的迭代器語法“yield return”。Yield return是一種延續的方式,它不會掛起一個真正的線程,而實現暫停線程執行並在以後喚醒的效果。這個特性一般用於迭代,不過結合了CCR就能擴展爲任意類型的異步操作。這樣做的最大好處是不需要大規模修改您的現有代碼。

2008 PDC中的這段示例代碼展示瞭如何使用端口來發起一個異步調用。與阻塞方式,或者在異步調用模式中使用顯式回調函數的方式不同,我們只要簡單的通過yield return語句來跳出函數即可。當獲得數據,同時有空餘線程時,函數就會“毫不知情”地從下一行代碼開始繼續執行。

fs.BeginRead(buffer, 0, buffer.Length, arPort.Post, null);

// yield until stream posts IAsyncResult on the CCR port

yield return arPort.Receive();

// extract result, it must be in the port

var ar = (IAsyncResult)arPort.Test();

int read = fs.EndRead(ar);

CCR有望被包含在.NET 4.0/Visual Studio 2010中。

查看英文原文:Erlang Style Concurrency for .NET Applications Part 1 - CCR

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章