Delphi多線程的OnTerminate屬性(附加一個關於臨界區線程同步的例子)

來源:互聯網
上載者:User

標籤:

  首先看TThread源碼中關於OnTerminate的代碼:

public    ....    property OnTerminate: TNotifyEvent read FOnTerminate write FOnTerminate;    ...end;

  再看Delphi內建的協助手冊中對於OnTerminate的解釋:

Occurs after the thread‘s Execute method has returned and before the thread is destroyed.

property OnTerminate: TNotifyEvent;

Description

Write an OnTerminate event handler to execute code after the thread finishes executing. The OnTerminate event handler is called in the context of the main thread, which means CLX methods and properties can be called freely.

  翻譯成中文的大致的解釋就是:線程的該屬性如果被賦值為一個方法,那麼此方法將會在該線程的Execute方法執行完成並退出,但是線程還沒有被釋放之前執行。

 

  一個實際的例子:

unit Unit1;interfaceuses  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,  Dialogs, StdCtrls;type  TForm1 = class(TForm)    btn1: TButton;    procedure btn1Click(Sender: TObject);  private    procedure ThreadDone(Sender: TObject);  public    { Public declarations }  end;  TTestThread = class(TThread)  protected    procedure Execute; override;  end;var  Form1: TForm1;implementation{$R *.dfm}const  MaxSize = 128;var  NextNumber: Integer = 0;  DoneFlags: Integer = 0;  GlobalArray: array[1..MaxSize] of Integer;  CS: TRTLCriticalSection;  function GetNextNumber: Integer;  begin    Result:= NextNumber;    Inc(NextNumber);  end;  procedure TTestThread.Execute;  var    i: Integer;  begin    OnTerminate:= Form1.ThreadDone;    //在這裡設定OnTerminate屬性為Form1的ThreadDone方法,表示線上程執行完Execute之後,還沒有被釋放之前,要緊接著執行Form1的ThreadDone方法。    EnterCriticalSection(CS);    for i:= 1 to MaxSize do    begin      GlobalArray[i]:= GetNextNumber;      Sleep(5);    end;    LeaveCriticalSection(CS);  end;  procedure TForm1.ThreadDone(Sender: TObject);  var    i: Integer;  begin    inc(DoneFlags);    if DoneFlags = 2 then    begin      for i:= 1 to MaxSize do        lst1.Items.Add(IntToStr(GlobalArray[i]));      DeleteCriticalSection(CS);    end;  end;procedure TForm1.btn1Click(Sender: TObject);begin  initializeCriticalSection(CS);  TTestThread.Create(False);  TTestThread.Create(False);end;end.

  先解釋OnTerminate:在這裡設定OnTerminate屬性為Form1的ThreadDone方法,表示線上程執行完Execute之後,還沒有被釋放之前,要緊接著執行Form1的ThreadDone方法。

  再對線程的同步進行說明:這裡使用臨界區進行線程的同步,該常式會在點擊按鈕之後開啟兩個線程。

               每個線程都是對一個全域數組GlobalArray進行操作,使用了臨界區的話,(看TForm1的btn1Click方法)雖然是連續開啟兩個線程,但是因為使用了臨界區,而且是線上程的Execute中進行操作之前先進入臨界區,所以當一個線程運行(也就是執行Execute方法)時,第一個線程進入臨界區對全域數組GlobalArray進行性操作,那麼另外一個線程就只能等待,等到第一個線程完成操作並且離開臨界區之後(此時GlobalArray數組的值是從0到127)。第二個線程開始進入臨界區,並且開始對GlobalArray進行操作,最後GlobalArray數組中的值是從128到255。

               通過使用臨界區就可以保證多個線程不能同時對一個資源進行操作,而如果沒有使用臨界區對線程進行同步的話,那麼最後可能是線程1、線程2隨機連續對數組進行操作(因為作業系統對線程的時間片的分配是隨機的)(還有NextNumber這個全域變數也會被兩個線程隨機連續操作,可能造成衝突),最後的結果就是當兩個線程都執行完成之後,GlobalArray數組中的值沒有任何規律,所以這時候就不可能根據規則來控制線程,這時候開發出來的程式就是開發人員所不能控制的,顯然不利於程式的穩定性等。

               所以在多個線程會去操作同一個資源等情況的時候,必須對線程進行同步,保證線程的可控性。

Delphi多線程的OnTerminate屬性(附加一個關於臨界區線程同步的例子)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.