程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Delphi >> 學習筆記: Delphi之線程類TThread,delphitthread

學習筆記: Delphi之線程類TThread,delphitthread

編輯:Delphi

學習筆記: Delphi之線程類TThread,delphitthread


新的公司接手的第一份工作就是一個多線程計算的小系統。也幸虧最近對線程有了一些學習,這次一接手就起到了作用。但是在實際的開發過程中還是發現了許多的問題,比如掛起與終止的概念都沒有弄明白,導致浪費許多的時間。

TThread-簡單的開始

在Delphi的VCL中封裝了一個TThread類用於多線程的開發,這樣比較符合面向對象的思想,同時又可以提高開發效率,一般的情況下開發都是通過派生這個類來實現多線程。所以重點還在這個類TThread上:   簡單的看一眼,這個類倒也簡單,就是封裝了線程的API,通過一個ThreadProc函數來完成了多線程整個過程。很容易就能派生一個線程類:
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。

線程釋放
一般線程創建後運行完會自動釋放,所以這裡的類裡我設置FreeOnTerminate := False;,這樣線程對象就不會自動釋放,這樣做的好處就是可以由線程對象以外的代碼來管理線程的生命周期,如果有的代碼需要控制線程對象的生命周期就可以用這個屬性來讓線程不自己釋放。  

ThreadProc-源代碼分析

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的真正作用在這呢,需要開發者自己來控制,當然這樣也就變的非常靈活了。

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved