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

多線程程式設計(9):掌握 WaitForSingleObject 等待函數

     編輯:Delphi

為什麼要先學 WaitForSingleObject?

在 Windows 多線程同步體系中,Mutex、Semaphore、Event、WaitableTimer 等所有核心同步物件,最終都仰賴 WaitForSingleObject(或其變體 WaitForMultipleObjects)來進行等待。它是同步編程的「通用鑰匙」,掌握它就能駕馭幾乎所有核心同步機制。

函數原型與返回值

function WaitForSingleObject(
  hHandle: THandle;       // 待等待的核心物件句柄
  dwMilliseconds: DWORD   // 等待逾時毫秒數,INFINITE 表示永久等待
): DWORD; stdcall;

主要返回值:

  • WAIT_OBJECT_0:等待成功,物件狀態變為「有訊號」。
  • WAIT_TIMEOUT:在指定時間內物件仍未有訊號,逾時返回。
  • WAIT_ABANDONED:僅 Mutex 會產生,表示擁有者線程終止卻未釋放 Mutex,系統強制釋放並喚醒等待者。

實戰範例:啟動記事本並監視其結束

此例展示如何用 CreateProcess 啟動外部進程,取得其進程句柄,再建立一條監視線程呼叫 WaitForSingleObject 等待進程結束,最後在主視窗顯示通知。

unit Unit1;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;
type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  end;
var Form1: TForm1;
implementation {$R *.dfm}
var hProcess: THandle; // 進程句柄

function MyThreadFun(p: Pointer): DWORD; stdcall;
begin
  // 無限等待進程結束
  if WaitForSingleObject(hProcess, INFINITE) = WAIT_OBJECT_0 then
    Form1.Caption := Format('進程 %d 已關閉', [hProcess]);
  Result := 0;
end;

procedure TForm1.Button1Click(Sender: TObject);
var pInfo: TProcessInformation; sInfo: TStartupInfo;
    Path: array[0..MAX_PATH-1] of Char; ThreadID: DWORD;
begin
  GetSystemDirectory(Path, MAX_PATH);
  StrCat(Path, '\notepad.exe');
  FillChar(sInfo, SizeOf(sInfo), 0);
  sInfo.cb := SizeOf(sInfo);
  if CreateProcess(Path, nil, nil, nil, False, 0, nil, nil, sInfo, pInfo) then
  begin
    hProcess := pInfo.hProcess;
    Caption := Format('進程 %d 已啟動', [hProcess]);
    CreateThread(nil, 0, @MyThreadFun, nil, 0, ThreadID); // 監視線程
  end;
end;
end.

執行效果

等待進程結束示意

點擊按鈕啟動記事本,關閉記事本後主視窗標題自動更新為「進程 xxx 已關閉」,證明等待函數正確捕捉到進程終止訊號。

補充說明

  • WaitForSingleObject 可等待的物件不只進程/線程,還包括 Event、Mutex、Semaphore、Timer、Console Input 等所有可同步的核心物件。
  • 實務上常搭配 INFINITE 使用,但需警惕死結;若需回應使用者介面,可考慮短逾時配合 MsgWaitForMultipleObjects 處理訊息佇列。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved