天天看點

TThread類詳解<轉>

TThread是一個抽象類,可以建立幾個獨立的線程。

類關系 TObject

在一個多線程的應用程式中建立一個TThread的後子類代表一個線程。每一新子類的TThread對象的執行個體是一個新的線程。從TThread派生的多線程

執行個體可以構成Delphi的多線程應用程式。

當一個應用程式運作時,應用程式就被載入記憶體準備執行。此時,它成為包含一個或多個線程的程序,每個線程含有資料、代碼和系統資

源。線程執行應用程式的部分内容,并由系統配置設定CPU時間。同一程序的所有線程共享同一位址空間,可以通路程序的全局變量。線程通過以下工

作改善應用的性能:管理多通信裝置的輸入。

區分任務的優先級。優先級高的處理緊急的任務。優先級低的處理其他任務。

以下是使用線程的一些建議:

同時跟蹤太多的線程消耗CPU時間。對單處理器系統,一個程序最多有16個線程。

當多個線程更新相同的資源時,應使線程同步以避免沖突。

大多數通路VCL對象和更新窗體的方法必須從主VCL線程内部調用。

屬性清單

FreeOnTerminate 線程終止時該對象是否自動删除

Handle 包含線程句柄

Priority 确定該線程相對于程序中其他線程的優先級

ReturnValue 傳回線程值

Suspended 訓示一線程是否被挂起

Terminated 表明線程被要求終止

ThreadID 辨別貫穿系統的線程

方法清單

~TThread 删除線程對象并釋放其戰用的記憶體空間

DoTerminate 産生一個OnTerminate事件

Execute 提供包含線程執行時所需代碼的抽象方法

Resume 重新執行一個挂起的線程

Suspend 挂起一個運作中的線程

Synchronize 在主VCL線程中執行Method

Terminate 将Ternimated屬性設定為True通知線程終止

TThread 建立一個線程對象的執行個體

WaitFor 等待線程終止并傳回ReturnValue屬性值

事件清單

OnTerminateExecute 方法已傳回且該線程被删除前發生

屬性

property OnTerminate: TNotifyEvent;确定當線程終止時,該線程對象是否自動删除。

FreeOnTerminate預設值為False,線程對象必須在代碼中顯示删除。

包含線程句柄。

當調用Win32API函數處理線程時,使用Handle.

TThread::Priority

__property TThreadPriority Priority = {read=GetPriority,write=SetPriority,nodefault};

确定該線程相對于程序中其他線程的優先級。

Priority屬性為一枚舉類型,其預設為tpNormal.

TThreadPriority類型定義了TThread元件的Priority屬性的可能值,如下表所述。Windows根據優先級确定每一個線程的CPU周期。

_____________________________________________________________________

值           含義

tpIdle 隻有當系統空閑時該線程執行

tpLowest 線程優先級比正常低2點

tpLower 線程優先級比正常低1點

tpNormal 線程優先級為正常值

tpHigher 線程優先級比正常高1點

tpHighest 線程優先級比正常高2點

tpTimeCritical 線程優先級最高

TThread::ReturnValue

__property int ReturnValue = {read=FReturnValue,write=FReturnValue,nodefault};

傳回線程值。

使用ReturnValue應用為其他線程訓示其成功/失敗或數字結果/輸出。WaitFor方法傳回存儲在ReturnValue中的值。

TThread::Suspended

__property bool Suspended = {read=FSuspended,write=SetSuspended,nodefault};

訓示一線程是否被挂起。

除非重新執行,否則被挂起的線程不會繼續執行。若将Suspended設定為True将挂起一個線程;若設定為False,則繼續執行該線程。

TThread::Terminated

__property bool Terminated = {read=FTerminated,nodefault};

表明線程被要求終止。Terminate方法将Terminated屬性設定為True。

線程的Execute方法和任何Execute調用的方法将周期性地檢查Terminated,當其為True時,将終止執行。

TThread::ThreadID

__property int ThreadID = {read=FhreadID,nodefault};

辨別貫穿系統的線程。

當調用Win32API函數處理線程時,ThreadID将十分有用。

注意:ThreadID與Handle屬性不同。

方法

TThread::~TThread

__fastcall virvual ~TThread(void);

删除線程對象并釋放其戰勝的記憶體空間。

在應用中不要調用~TThread。用delete替代。

~TThread通知線程終止,并在調用Destroy方法前等待該線程傳回。

TThread::DoTerminate

virtual void __fastcall DoTerminate(void);

産生一個OnTerminate事件。

DoTerminate調用OnTerminate時間句柄,但并不終止該線程。

TThread::Execute

virtual void __fastcall Execute(void) =0;

提供包含線程執行時所需代碼的抽象方法。

Execute檢視Terminated屬性值以決定該線程是否需要終止。

當CreateSuspended被設定為False,當調用Create時,一線程執行;線上程建立後先調用了Resume且CreateSuspended為True,一線程執行。

注意:不要線上程的Execute方法中直接調用其他對象的屬性和方法。應該将對其他對象的使用分成幾個不同的過程,将其作為一個傳遞到

Synchronize方法的參數分别調用。

TThread::Resume

void __fastcall Resume(void);

重新執行一個挂起的線程。

調用Suspend可以嵌套。是以調用Resume必須注意次序。

TThread::Suspend

void __fastcall Suspend(void);

挂起一個運作中的線程。

調用Resume可以繼續運作。調用Suspend可以嵌套。是以調用Resume必須次序。

TThread::Synchronize

typedef void __fastcall(__closure* TThreadMethod)(void);

void __fastcall Synchronize (TThreadMethod&Method);

在主VCL線程中執行Method。

Synchronize方法由Method指定的調用被主VCL線程執行。

注意:當在主VCL線程中執行Method時,目前的線程被挂起。

TThread::Terminate

void __fastcall Terminate(void);

通過将Terminated屬性設定為True通知線程終止。

線程的Execute方法以及Execute調用的任何方法應周期性的檢查Terminated,當其為True時終止運作。

TThread::TThread

__fastcall TThread(bool CreateSuspended);

建立一個線程對象的執行個體。

在應用中不要直接使用TThread來建立線程。用new替代,傳遞CreateSuspended參數argument。若CreateSuspended為False,Execute被立即調用。若

CreateSuspended為True,Execute直到Resume被調用後才被調用。

TThread::WaitFor

int __fastcall WaitFor(void);

等待線程終止并傳回ReturnValue屬性值。

直到線程終止時WaitFor才傳回,是以線程一定是因為結束了Execute方法或因Terminated屬性為了True而終止。如果該線程使用Synchronize,則不要

在主VCL線程中調用WaitFor,否則或者引起系統當機,或者産生一個EThread異常。

Synchronize在允許該方法生效前等待主VCL線程進入資訊回路。若主VCL線程已經調用了WaitFor,它将不會進入資訊回路,Synchronize也永遠不會返

回。此時,TThread将産生一個EThread意外并使該線程終止;而且如果該意外沒有被Execute方法截獲,該應用也将終止。如果調用WaitFor時,

Synchronize已經在VCL線程中等待,TThread将不會幹預,應用程式将當機。

事件

TThread::OnTerminate

__property TNotifyEvent OnTerminate = {read=FOnTerminate,write=FOnTerminate};

當線程的Execute方法已經傳回且在該線程被删除之前發生。

OnTerminate事件句柄在主VCL線程被調用。該線程對象也可在該事件中被釋放。

在是使用TThread時将會用到Classes單元中定義的9個函數,這9個函數為TThread提供同步管理

下面就來分析一下,這幾個函數,在函數中用到的幾個單元變量

                       var

                        SyncList: TList = nil;//統計同時調用同步方法的線程對象

                        ThreadLock: TRTLCriticalSection;

                        ThreadCount: Integer;//統計程序中的線程數量

1.InitThreadSynchronization

    這個函數功能是初始化臨界區和建立事件對象

procedure InitThreadSynchronization;

begin

  InitializeCriticalSection(ThreadLock);//初始化臨界區

  SyncEvent := CreateEvent(nil, True, False, '');//建立事件對象

  if SyncEvent = 0 then

    RaiseLastOSError;

end;

2.DoneThreadSynchronization

   這個函數的功能是銷毀同步對象

procedure DoneThreadSynchronization;

  DeleteCriticalSection(ThreadLock);//删除臨界區

  CloseHandle(SyncEvent);//關閉事件對象

3.ResetSyncEvent

   将SyncEvent置為無信号狀态

procedure ResetSyncEvent;

   ResetEvent(SyncEvent);

4.WaitForSyncEvent(Timeout: Integer);

   在一定時間内,如果SyncEvent為有信号狀态Reset SyncEvent

procedure WaitForSyncEvent(Timeout: Integer);

  if WaitForSingleObject(SyncEvent, Timeout) = WAIT_OBJECT_0 then

    ResetSyncEvent;

5.SignalSyncEvent

   置SyncEvent為有信号狀态

procedure SignalSyncEvent;

  SetEvent(SyncEvent);

6.AddThread

将ThreadCount加1,原子執行

procedure AddThread;

  InterlockedIncrement(ThreadCount);

7.RemoveThread

将ThreadCount減1,原子執行

procedure RemoveThread;

  InterlockedDecrement(ThreadCount);

8.CheckSynchronize

  主線程對子線程同步,使得在多個子線程同時執行同步方法時,以循環的方式執行,隻能在主線程中調用(1)

  主線程隻有一個,子線程有多個,多個子線程同時調用同步方法是需要進行同步,用一個TList對象儲存這寫對象

 在TApplication.idle中被調用

function CheckSynchronize(Timeout: Integer = 0): Boolean;

var

  SyncProc: PSyncProc;

  LocalSyncList: TList;

  if GetCurrentThreadID <> MainThreadID then//(1)不是主線程就扔出一個異常

    raise EThread.CreateResFmt(@SCheckSynchronizeError, [GetCurrentThreadID]);

  if Timeout > 0 then

    WaitForSyncEvent(Timeout)

  else

    ResetSyncEvent;//所有等待線程将停止執行,

  LocalSyncList := nil;

  EnterCriticalSection(ThreadLock);//進入臨界區,對SyncList和LocalSyncList進行保護,;

  try

    Integer(LocalSyncList) := InterlockedExchange(Integer(SyncList), Integer(LocalSyncList));

// 交換Integer(SyncList), Integer(LocalSyncList));

    try

      Result := (LocalSyncList <> nil) and (LocalSyncList.Count > 0);

      if Result then

      begin

        while LocalSyncList.Count > 0 do

        begin

          SyncProc := LocalSyncList[0];

          LocalSyncList.Delete(0);

          LeaveCriticalSection(ThreadLock);

          try

            try

              SyncProc.SyncRec.FMethod;//執行同步方法

            except

              SyncProc.SyncRec.FSynchronizeException := AcquireExceptionObject;

            end;

          finally

            EnterCriticalSection(ThreadLock);

          end;

          SetEvent(SyncProc.signal);

        end;

      end;

    finally

      LocalSyncList.Free;

    end;

  finally

    LeaveCriticalSection(ThreadLock);

  end;

9.線程函數,在CreateThread中将會使用,此函數間會調用Thread.Execute;

function ThreadProc(Thread: TThread): Integer;

  FreeThread: Boolean;

    if not Thread.Terminated then

      Thread.Execute;

    except

      Thread.FFatalException := AcquireExceptionObject;

    FreeThread := Thread.FFreeOnTerminate;

    Result := Thread.FReturnValue;

    Thread.DoTerminate;

    Thread.FFinished := True;

    SignalSyncEvent;

    if FreeThread then Thread.Free;

    EndThread(Result);

繼續閱讀