非同步,平行執行技術,從Delphi到Delphi Prism,再到未來的Delphi?

前一陣子Delphi的現任總架構師Allen Bauer討論了許多有關非同步和平行處理的文章,而更早MS也在.NET平台上推出Microsoft Parallel Extensions to Framework 3.5套件,開始進行對於平行開發技術的演進,這個趨勢是想見而知的,因為現今的CPU都是多核心,每一個核心又都支援多執行緒執行的能力,因此軟體技術如何搭配硬體的進步,進而發揮硬體的計算能力是軟體突破的重要方向之一。如果各位嗅覺靈敏的話,從Allen的一系列文章以及他的研究方向來看,各位應該可以開始猜測未來Delphi的發展方向了。
除了這些蛛絲馬跡之外,CodeGear最近又宣佈了Delphi Prism,Delphi Prism除了是一個獨立的產品之外,也將和Delphi/C++Builder 2009整合為RAD Studio 2009,提供在.NET方面的解決方案。不過Delphi Prism並不是Delphi.NET,Delphi Prism是.NET平台上使用類似Delphi語法的程式語言,並且包含了許多先進的程式語言功能。有趣的是Delphi Prism已經在程式語言本身加入了許多非同步,平行執行功能,當結合Microsoft PFX framework時,能夠自動使用PFX中的平行執行技術。

今天我在CodeGear的部落格上看到了Andreano討論有關Delphi Prism的文章,其中就有討論到Delphi Prism程式語言中使用關鍵字async來建立非同步執行的範例,我覺得蠻有意思的,因為這代表現在可以開始討論Delphi Prism了。在Andreano的範例中,他使用了async來宣告一個方法,在Delphi Prism中使用async關鍵字宣告的方法就合格成為一個非同步執行的方法,讓我使用一個範例來說明一下。
在下面的程式碼中宣告了5個類別方法,以及兩個使用async宣告的非同步方法CallLoops和CallParallelLoops:

type
  ConsoleApp = class
  public
    class method Main;
    class method CallAsyncMethod;
    class method CallAsyncWithParallel;
    class method Linq;
    class method PLinq;
    method CallLoops(iID : Integer) ; async;
    method CallParallelLoops(iID : Integer); async;
  end;

接著我在類別方法Main中呼叫其他四個類別方法:

class method ConsoleApp.Main;
begin
  ConsoleApp.CallAsyncMethod; 
  ConsoleApp.CallAsyncWithParallel;
  ConsoleApp.Linq;
  ConsoleApp.PLinq;
end;

在CallAsyncMethod中,它在一個迴圈中呼叫了使用async宣告的CallLoops方法,因此.NET會產生四個執行緒來執行CallLoops:

class method ConsoleApp.CallAsyncMethod;
begin
  Console.WriteLine(‘開始執行非同步方法’);

  with lConsoleApp := new ConsoleApp() do
  begin
    for i : Integer := 0 to 4 do
       lConsoleApp.CallLoops(i);
  end;
  Console.WriteLine(‘結束執行非同步方法’);
  Console.ReadLine;
end;

而CallLoops方法只是很簡單的執行一個迴圈,列印訊息並且使用Thread在每一次迴圈暫時暫停0.1秒。

method ConsoleApp.CallLoops(iID : Integer) ;
begin
  for i : Integer := 0 to 4 do
  begin
    Console.WriteLine(‘執行緒’ + iID.ToString + ‘ : ‘ + i.ToString);
    System.Threading.Thread.Sleep(100);
  end;
    Console.WriteLine(‘執行緒’ + iID.ToString + ‘執行完成’);
end;

讓我們看看這個執行的結果,從下圖中讀者可以看到.NET果然以四個執行緒,以不定的次序執行每一個執行緒,所以在Delphi Prism中要開發非同步執行的方法非常的簡單的,只要使用關鍵字async來宣告方法即可。

http://blufiles.storage.live.com/y1peVkQA8uAo_Fv5OSB6PgOgi86eB7sFjTSjxNwMu1dcbMswRKjjjGjB6JJJu_YRiI8

然而讀者如果仔細觀察上圖的執行狀態,會發現雖然四個執行緒以不定的次序執行,但是每一個執行緒在執行CallLoops方法的迴圈時仍然是以順序的方式在執行迴圈,這代表CallLoops雖然是在獨立的執行緒中執行,但仍然沒有使用平行執行技術。但在Delphi Prism中我們只需要使用一個parallel關鍵字就可以立刻使用Microsoft PFX framework提供的平行技術。
例如下面的CallAsyncWithParallel使用了幾乎和CallAsyncMethod一樣的程式碼,只是CallAsyncWithParallel呼叫了非同步方法CallParallelLoops:

class method ConsoleApp.CallAsyncWithParallel;
begin
  Console.WriteLine(‘開始執行非同步, 並行方法’);

  with lConsoleApp := new ConsoleApp() do
  begin
    for i : Integer := 0 to 4 do
       lConsoleApp.CallParallelLoops(i);
  end;
  Console.WriteLine(‘結束執行非同步, 並行方法’);
  Console.ReadLine;
end;

而CallParallelLoops也幾乎和CallLoops一樣,只是注意CallParallelLoops在呼叫for迴圈時使用了另外一個關鍵字parallel

method ConsoleApp.CallParallelLoops(iID : Integer) ;
begin
  for parallel i : Integer := 0 to 4 do
  begin
    Console.WriteLine(‘執行緒’ + iID.ToString + ‘ : ‘ + i.ToString);
    System.Threading.Thread.Sleep(100);
  end;
    Console.WriteLine(‘執行緒’ + iID.ToString + ‘執行完成’);
end;

在Delphi Prism中如果使用關鍵字parallel而且開發人員參考了Microsoft PFX framework,那麼Delphi Prism便會編譯出如下的程式碼:

method ConsoleApp.@AsyncProc_0_CallParallelLoops(iID: Int32);
beginvar c__1: <>c__0 := new <>c__0;
c__1.iID := iID;
Parallel.&For(0, 5, 1, new Action<Int32, ParallelState>(c__1,<CallParallelLoops>__0));
Console.WriteLine(String.Concat('執行緒', iID.ToString, '執行完成'))
end;

在上面的程式碼中Delphi Prism編譯器會自動產生PFX的Parallel.For的程式碼提供平行執行for迴圈的能力。
下圖是CallAsyncWithParallel執行的結果,讀者可以仔細觀察,CallAsyncWithParallel也產生了四個執行緒來執行,但是每一個執行緒在執行CallParallelLoops迴圈時卻不是以順序的方式來執行,而是使用平行的方式執行for迴圈。
http://blufiles.storage.live.com/y1pOShWV2i4BG0HEKm6wd1hBLqfXEwbjFJiabr50xz62y69ZbFYromv4M1tcIYSiMI8

 從上面的討論中我們可以瞭解Delphi Prsim提供了非常方便的非同步和平行處理的機制,讓開發人員能夠在結合PFX時開發出平行執行架構。
在下次的文章中讓我們再看看Delphi Prism在支援Linq和平行Linq時是多麼的方便。

廣告
  1. #1 by wangwi on 2008 年 11 月 25 日 - 07:06:46

    李老师,你好;     在codegear的官方网站上看到了rad2009包括了Delphi Prism的消息,可是delphi.net呢?而且也看不到ECO的影子了,这样一个很有前途的工具难道就此放弃了吗?如果这样的话,大家会对codegear很失望的,一个产品发布了,甚至有了很多的使用者,可说停止就停止了,似乎有些儿戏了。

  2. #2 by on 2008 年 11 月 28 日 - 10:10:05

    我同意你說的ECO是Delphi.NET中最吸引人的技術, 我自己也非常喜歡ECO, 當我知道Delphi Prism中沒有ECO時我個人也很失望, 但"不在其位, 不謀其政", 產品一致性的問題應該請客戶反應給CodeGear知道了.

發表迴響

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com 標誌

您的留言將使用 WordPress.com 帳號。 登出 /  變更 )

Google+ photo

您的留言將使用 Google+ 帳號。 登出 /  變更 )

Twitter picture

您的留言將使用 Twitter 帳號。 登出 /  變更 )

Facebook照片

您的留言將使用 Facebook 帳號。 登出 /  變更 )

連結到 %s

%d 位部落客按了讚: