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

Delphi 多線程程式設計(5):CreateThread 入口函數回傳值與 GetExitCodeThread 判斷執行緒狀態

     編輯:Delphi

前言

承接前文,深入探討 CreateThread 入口函數的回傳值機制、GetExitCodeThread 取得結束代碼判斷執行緒是否結束,以及如何在執行緒中呼叫 VCL 物件方法。

一、入口函數回傳值即執行緒結束代碼

CreateThread 的第三個參數 lpStartAddress 指向的函數原型:

function ThreadFunc(Parameter: Pointer): DWORD; stdcall;

Delphi System 單元定義 TThreadFunc = function(Parameter: Pointer): Integer,建議統一使用 DWORD 以符合 Win32 規範。

此回傳值會成為執行緒的 Exit Code。執行緒結束後,主執行緒可呼叫:

function GetExitCodeThread(hThread: THandle; var lpExitCode: DWORD): BOOL; stdcall;
  • 若執行緒仍在執行,lpExitCode = STILL_ACTIVE (259)。
  • 若已結束,lpExitCode 即為入口函數的回傳值。

二、執行緒呼叫表單類別方法

入口函數不能直接是類別方法(方法指標包含隱藏的 Self,呼叫慣例不同)。解決方案:入口函數為全域函數,內部轉呼叫表單實例的方法。

type
  TForm1 = class(TForm)
    Button1, Button2: TButton;
    procedure Button1Click(Sender: TObject);  { 建立執行緒 }
    procedure Button2Click(Sender: TObject);  { 檢查結束代碼 }
  private
    procedure FormProc;  { 供執行緒呼叫的方法 }
  end;

var
  hThread: THandle;

function MyThreadFun(p: Pointer): DWORD; stdcall;
begin
  Form1.FormProc;       { 呼叫表單方法 }
  Result := 99;         { 自訂結束代碼 }
end;

procedure TForm1.FormProc;
var
  i: Integer;
begin
  for i := 0 to 200000 do
  begin
    with Canvas do
    begin
      Lock;
      TextOut(10, 10, IntToStr(i));
      Unlock;
    end;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  ID: DWORD;
begin
  hThread := CreateThread(nil, 0, @MyThreadFun, nil, 0, ID);
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  ExitCode: DWORD;
begin
  if hThread = 0 then
  begin
    Caption := '執行緒尚未啟動';
    Exit;
  end;
  GetExitCodeThread(hThread, ExitCode);
  if ExitCode = STILL_ACTIVE then
    Caption := Format('執行緒執行中 (ExitCode=%d)', [ExitCode])
  else
    Caption := Format('執行緒已結束,結束代碼=%d', [ExitCode]);
end;

三、執行畫面

執行緒結束代碼示範

四、關鍵提醒

  • Canvas 存取必須 Lock/Unlock:VCL 非執行緒安全,多執行緒同時繪圖會導致 GDI 物件損壞或 AV。
  • 結束代碼慣例:0 表成功,非 0 表錯誤碼;自訂代碼(如 99)僅供應用層協議使用。
  • 句柄管理:CreateThread 回傳的 hThread 需在適當時機 CloseHandle,否則核心物件洩漏。若使用 TThread 類別,FreeOnTerminate := True 會自動處理。
  • 現代寫法:新專案建議直接使用 TThread 或 TTask.Run (PPL),僅在需極致效能或整合舊 API 時使用 CreateThread。

結語

掌握 GetExitCodeThread 判斷執行緒狀態,結合全域函數轉呼叫物件方法,是純 API 多線程開發的核心技巧。理解這層機制,有助於除錯執行緒同步、資源釋序與異常處理等進階議題。

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