TMyThread = class(TThread)
private
FCount: Integer;
FOnShowValue: TGetStrProc;
protected
procedure Execute; override;
public
constructor Create;
property Count: Integer read FCount;
property OnShowValue: TGetStrProc read FOnShowValue write FOnShowValue;
end;
{ TMyThread }
constructor TMyThread.Create;
begin
inherited Create(False);
FCount := 0;
FreeOnTerminate := False;
end;
procedure TMyThread.Execute;
begin
while not self.Terminated do
begin
Inc(FCount);
if Assigned(FOnShowValue) then
FOnShowValue(IntToStr(FCount));
Sleep(100);
end;
end;
代碼中只覆蓋了一個Execute方法即可,其他的代碼都是業務相關的代碼,還是非常簡單好用。
線程掛起
線程還支持掛起的功能,即讓CPU將線程中斷,保留現場,不再分配時間片,這樣線程就像死了一般,直到再次喚醒線程再恢復現場繼續執行。線程終止
在Delphi的TThread類實現中,可以通過一個Terminate方法來讓線程終止。但事實上Terminated只是一個標識而已,在線程啟動時這個標識為False。
線程釋放function ThreadProc(Thread: TThread): Integer;
var
FreeThread: Boolean;
begin
{$IFDEF LINUX}
if Thread.FSuspended then sem_wait(Thread.FCreateSuspendedSem);
{$ENDIF}
try
if not Thread.Terminated then
try
Thread.Execute;
except
Thread.FFatalException := AcquireExceptionObject;
end;
finally
FreeThread := Thread.FFreeOnTerminate;
Result := Thread.FReturnValue;
Thread.FFinished := True;
Thread.DoTerminate;
if FreeThread then Thread.Free;
{$IFDEF MSWINDOWS}
EndThread(Result);
{$ENDIF}
{$IFDEF LINUX}
// Directly call pthread_exit since EndThread will detach the thread causing
// the pthread_join in TThread.WaitFor to fail. Also, make sure the EndThreadProc
// is called just like EndThread would do. EndThreadProc should not return
// and call pthread_exit itself.
if Assigned(EndThreadProc) then
EndThreadProc(Result);
pthread_exit(Pointer(Result));
{$ENDIF}
end;
end;
對於TThread的一個關鍵部分就是這個ThreadProc方法,它是線程創建時傳給系統API的回調函數;Delphi中通過這個方法完成了一個核心的功能,可以看到代碼中調用了Execute方法。這也就是為什麼派生類只要覆寫這個方法的原因。
所以從代碼也可以看出,線程啟動後代碼是順序執行的,代碼走完就結束了,所以為了讓線程能夠一直在運行就要在Execute方法裡加上一個死循環,保證線程一直在運算,直到接收到Terminated時才讓線程結束掉。所以Terminated的真正作用在這呢,需要開發者自己來控制,當然這樣也就變的非常靈活了。