首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> Delphi

Delphi TThread 線程類深度解析 (二):建構子、線程函數、同步機制與例外處理完整源碼走讀

     編輯:Delphi

建構子:線程創建核心


constructor TThread.Create(CreateSuspended: Boolean);
begin
  inherited Create;
  AddThread; // 全域線程計數 +1 (原子操作)
  FSuspended := CreateSuspended;
  FCreateSuspended := CreateSuspended;
  // 創建底層線程,進入掛起狀態
  FHandle := BeginThread(nil, 0, @ThreadProc, Pointer(Self), CREATE_SUSPENDED, FThreadID);
  if FHandle = 0 then
    raise EThread.CreateResFmt(@SThreadCreateError, [SysErrorMessage(GetLastError)]);
end;

關鍵點

  • AddThread/RemoveThread:使用 InterlockedIncrement/Decrement 維護全域 ThreadCount,保證線程安全 (原子操作,不可中斷)。
  • BeginThread:Delphi RTL 封裝的跨平台線程創建函數,參數 3 為線程函數 ThreadProc,參數 4 傳遞 Self。
  • CREATE_SUSPENDED:創建後暫不執行,由 AfterConstruction 依 CreateSuspended 決定是否 Resume。

線程函數 ThreadProc:執行核心 (全域函數)


function ThreadProc(Thread: TThread): Integer;
var
  FreeThread: Boolean;
begin
  try
    if not Thread.Terminated then
      try
        Thread.Execute; // 執行使用者覆寫的 Execute
      except
        Thread.FFatalException := AcquireExceptionObject; // 捕獲例外
      end;
  finally
    FreeThread := Thread.FFreeOnTerminate;
    Result := Thread.FReturnValue;
    Thread.DoTerminate; // 觸發 OnTerminate (透過 Synchronize)
    Thread.FFinished := True;
    SignalSyncEvent; // 通知等待者
    if FreeThread then Thread.Free; // 自動釋放
    EndThread(Result); // 結束線程
  end;
end;

流程解析

  1. 檢查 Terminated 標誌,未終止則呼叫 Execute
  2. Execute 發生例外 → 存入 FFatalException
  3. DoTerminate → Synchronize(CallOnTerminate) → 執行 OnTerminate 事件 (在主線程執行!)
  4. 設置 FFinished、發送 SyncEvent (供 WaitFor 等待)
  5. 若 FreeOnTerminate 則自動 Free
  6. EndThread 結束底層線程

同步機制:Synchronize 詳解


procedure TThread.Synchronize(Method: TThreadMethod);
var
  SyncRec: TSynchronizeRecord;
begin
  SyncRec.FThread := Self;
  SyncRec.FMethod := Method;
  SyncRec.FProcedure := nil;
  Synchronize(@SyncRec); // 類別方法,推送到主線程佇列
end;
  • 將方法封裝為記錄,推送到主線程處理佇列
  • 主線程訊息循環中處理 (CheckSynchronize),同步執行
  • 呼叫線程阻塞等待,直到主線程執行完畢
  • 因此 OnTerminate (在 Synchronize 中) 實際運行於主線程,可安全操作 VCL

關於「同步」譯名的學術註記

文中引用滑鐵盧大學李明教授觀點:英文 Synchronize 在線程語境下意為「協調一致」而非「同時發生」。中文慣用「同步」易誤解,但已成約定俗成。

DoTerminate 與 OnTerminate


procedure TThread.DoTerminate;
begin
  if Assigned(FOnTerminate) then Synchronize(CallOnTerminate);
end;

procedure TThread.CallOnTerminate;
begin
  if Assigned(FOnTerminate) then FOnTerminate(Self);
end;

SignalSyncEvent 與 WaitFor


procedure SignalSyncEvent;
begin
  SetEvent(SyncEvent); // 全域 Event,通知 WaitFor
end;

function TThread.WaitFor: LongWord;
begin
  if not FFinished then
    WaitForSingleObject(SyncEvent, INFINITE); // 等待線程結束
  Result := FReturnValue;
end;

總結

TThread 封裝了完整的線程生命週期:原子計數 → BeginThread 創建 → ThreadProc 執行 Execute → 例外捕獲 → Synchronize 觸發 OnTerminate (主線程) → Event 通知 WaitFor → 自動/手動釋放。理解這套機制,能正確使用 FreeOnTerminate、Synchronize、WaitFor、OnTerminate,避免常見的跨線程 VCL 操作錯誤、死鎖、記憶體洩漏。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved