Delphi的多線程開發執行個體

來源:互聯網
上載者:User

在軟體開發的過程中,多線程的開發應用有著極為重要的位置,使用多線程可以讓軟體系統

能夠並行操作、同時也能提高其運行效率。作為軟體開發人員的必修課之一,多線程的熟練

運用可以讓軟體系統有更佳的效能表現。

以下使用Window Api、Delphi 封裝的TThread類來分別建立線程,再以普通方法來執行

一個耗時的過程,對比使用線程的好處。

1. Windows API 函數直接建立
   主要是CreateThread 函數,其函數式如下:
    HANDLE CreateThread(
        // 安全執行緒屬性,預設用Nil
        LPSECURITY_ATTRIBUTES lpThreadAttributes,
        // 線程分配的堆棧大小,預設為0,系統自動分配 
        DWORD dwStackSize,      
        // 線程函數入口地址,要求是不帶參數的全域性的方法
        LPTHREAD_START_ROUTINE lpStartAddress,
        // 傳遞給線程的參數值 
        LPVOID lpParameter,
        // 建立線程的標識,如CREATE_SUSPENDED (掛起)
        DWORD dwCreationFlags, 
        //返回的線程標識identifier
        LPDWORD lpThreadId     
        ); 
如果線程建立成功,傳回值為其控制代碼值 .

在Delphi 項目中建立一個表單,寫下以下線程函數,以便調用
procedure APIThread1;
var i,cId:Integer;
begin
   with Form2 do
   begin
      for i:=1 to imax do
      begin
        EnterCriticalSection(Rtl);
        cId := GetCurrentThreadId ; //擷取當前執行的線程標識
        Memo1.Lines.Add('Thread ID '+inttostr(cId)+ ' : '+inttostr(i));
        LeaveCriticalSection(Rtl);
      end;
   end;
end;

為防止多個線程同時訪問(讀寫)同一個VCL資源引起出錯,使用了臨界變數 Rtl,
所以要聲明一個局部的臨界變數
Var
  Rtl : TRTLCriticalSection;

其作用相當於一個協議鎖,比如: 當APIThread1 函數,被CreateThread

(nil,0,@APIThread1,nil,0,hid)
調用多次產生不同線程時,由雩都對Memo1 執行了寫入操作,其中一個線程在寫入的過

程中,用Rtl臨界變數告訴其它正要訪問的線程:"我正在使用,請稍等。"
 
注意:
進入臨界區EnterCriticalSection(Rtl) 和離開臨界區LeaveCriticalSection(Rtl)是
配對的,所以要確保正常進入,正常離開,在使用臨界區變數前,必需先初始化,

InitializeCriticalSection(Rtl),用完後釋放DeleteCriticalSection(Rtl);

2.  使用Delphi 封裝的TThread 類建立
     主要是繼承TThread 類,在TThread 類的核心方法Execute中執行你想要的作業碼.
其實,通過查看TThread 類的原始碼可知,TThread同樣是調用CreateThread函數建立線

程,只是封裝/簡化了部分線程的應用細節,同時也納入部分安全考慮,這無疑為開發人

員提供了調用上的方便。
     方法中常用的線程掛起Suspend,喚醒Resume,中止Terminate等方法,可查閱相關

資料說明,這裡僅作線程的簡單調用例子。
  
先聲明繼承類
type
  TMyThread =class(TThread)

  private
    FFlag:Integer;
    procedure AccessVcl;
  protected
    procedure Execute ; override;
  public
     constructor Create(aFlag:Integer);
  end;

在implementation部分寫下方法內容
constructor TMyThread.Create(aFlag: Integer);
begin
  inherited Create(Suspended) ;
  FreeOnTerminate := true;
  FFlag := aFlag;
end;

procedure TMyThread.Execute;
begin
  inherited;
  AccessVcl;
  //Synchronize(AccessVcl);
end;

procedure TMyThread.AccessVcl;
var i:Integer;
begin
   with Form2 do
   begin
      for i:=1 to iMax do
        Memo1.Lines.Add('My Thread '+Inttostr(FFlag)+' : '+inttostr(i));
   end;
end;

調用執行線程:TMyThread.Create(10);

3. 再寫一個普通的for 迴圈執行某個比較花費時間的操作方法
  for i:=1 to imax do
  begin
    cId := GetCurrentThreadId ;
    Memo1.Lines.Add('Thread ID '+inttostr(cId)+ ' : '+inttostr(i));
  end;

在表單上分別調用API 線程方法,Delphi TThread 線程類方法,普通操作方法,再比較

執行效果,即時可以體現線程方法與非線程的好處。

 

全部源碼如下:

view plaincopy to clipboardprint?
unit Unit2;  
 
interface 
 
uses 
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,  
  Dialogs, StdCtrls;  
 
type 
  TForm2 = class(TForm)  
    Memo1: TMemo;  
    BtnThread1: TButton;  
    BtnThread2: TButton;  
    BtnNoThread: TButton;  
    Button1: TButton;  
    BtnClear: TButton;  
    BtnMyThread: TButton;  
    Button2: TButton;  
    procedure BtnThread1Click(Sender: TObject);  
    procedure BtnThread2Click(Sender: TObject);  
    procedure BtnNoThreadClick(Sender: TObject);  
    procedure Button1Click(Sender: TObject);  
    procedure BtnClearClick(Sender: TObject);  
    procedure BtnMyThreadClick(Sender: TObject);  
    procedure Button2Click(Sender: TObject);  
  private 
    { Private declarations } 
  public 
    { Public declarations } 
  end;  
 
{繼承的線程類} 
type 
  TMyThread =class(TThread)  
 
  private 
    FFlag:Integer;  
    procedure AccessVcl;  
  protected 
    procedure Execute ; override;  
 
  public 
     constructor Create(aFlag:Integer);  
  end;  
 
const 
   iMax = 2000 ;  
 
var 
  Form2: TForm2;  
  Rtl : TRTLCriticalSection;  
  Thd1,Thd2 : Cardinal;  
 
implementation 
 
{$R *.dfm} 
 
//API 線程方法  
procedure APIThread1;  
var i,cId:Integer;  
begin 
   with Form2 do 
   begin 
      for i:=1 to imax do 
      begin 
        EnterCriticalSection(Rtl);  
        cId := GetCurrentThreadId ;  
        Memo1.Lines.Add('Thread ID '+inttostr(cId)+ ' : '+inttostr(i));  
        LeaveCriticalSection(Rtl);  
      end;  
   end;  
end;  
 
constructor TMyThread.Create(aFlag: Integer);  
begin 
  inherited Create(Suspended) ;  
  FreeOnTerminate := true;  
  FFlag := aFlag;  
end;  
 
procedure TMyThread.Execute;  
begin 
  inherited;  
  AccessVcl;  
  //Synchronize(AccessVcl);  
end;  
 
procedure TMyThread.AccessVcl;  
var i:Integer;  
begin 
   with Form2 do 
   begin 
      for i:=1 to iMax do 
        Memo1.Lines.Add('My Thread '+Inttostr(FFlag)+' : '+inttostr(i));  
   end;  
end;  
 
procedure TForm2.BtnThread1Click(Sender: TObject);  
var Hid:THandle;  
begin 
  //API線程調用1  
  Thd1:= CreateThread(nil,0,@APIThread1,nil,0,hid);  
end;  
 
procedure TForm2.BtnThread2Click(Sender: TObject);  
var Hid:THandle;  
begin 
  //API線程調用2  
  Thd2:= CreateThread(nil,0,@APIThread1,nil,0,hid);  
end;  
 
procedure TForm2.BtnNoThreadClick(Sender: TObject);  
var i,cid:Integer;  
begin 
  //普通方法執行for 迴圈  
  for i:=1 to imax do 
  begin 
    cId := GetCurrentThreadId ;  
    Memo1.Lines.Add('Thread ID '+inttostr(cId)+ ' : '+inttostr(i));  
  end;  
end;  
 
procedure TForm2.Button1Click(Sender: TObject);  
begin 
   ShowMessage('同時執行其它操作');  
end;  
 
procedure TForm2.BtnClearClick(Sender: TObject);  
begin 
  Memo1.Lines.Clear;  
end;  
 
procedure TForm2.BtnMyThreadClick(Sender: TObject);  
begin 
  //Delphi TThread繼承類的調用方法  
  TMyThread.Create(11);  
end;  
 
procedure TForm2.Button2Click(Sender: TObject);  
var ext:THandle;  
begin 
  GetExitcodeThread(Thd1,Ext);  
  TerminateThread(Thd1,ext);  
  //LeaveCriticalSection(Rtl);  
end;  
 
initialization 
    InitializeCriticalSection(Rtl);  
 
finalization 
    DeleteCriticalSection(Rtl);  
 
end. 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.