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

Delphi 多線程同步:使用 Mutex 實現程式防重複啟動

     編輯:Delphi

前言

在 Windows 程式開發中,防止使用者重複啟動同一個應用程式是常見需求。與關鍵區段不同,Mutex(互斥物件)屬於核心物件,支援跨進程同步,非常適合實現單一實例應用程式。本文將詳細介紹如何利用 OpenMutex 與 CreateMutex 達到此目的,並提供完整的 Delphi 程式碼範例。

核心邏輯

  1. 嘗試以 OpenMutex 開啟一個自訂名稱的 Mutex 物件。
  2. 若開啟失敗(回傳 0),表示該 Mutex 不存在,隨即呼叫 CreateMutex 建立它,代表這是首次啟動。
  3. 若開啟成功,說明程式已在執行中,直接終止新啟動的實例。
  4. 程式結束時,以 CloseHandle 釋放 Mutex。

關鍵 API 宣告

function OpenMutex(
  dwDesiredAccess: DWORD; { 存取權限 }
  bInheritHandle: BOOL;   { 是否可被子進程繼承 }
  pName: PWideChar        { Mutex 物件名稱 }
): THandle; stdcall;      { 成功返回句柄,失敗返回 0 }

注意: CreateMutex 的第二個參數(初始擁有權)在這裡不再關鍵,因為判斷依據是 Mutex 的名稱是否已存在。

表單單元實作範例

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs;

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

var
  hMutex: THandle;
const
  NameMutex = 'MyUniqueAppMutex';

procedure TForm1.FormCreate(Sender: TObject);
begin
  { 嘗試開啟已存在的 Mutex }
  if OpenMutex(MUTEX_ALL_ACCESS, False, NameMutex) <> 0 then
  begin
    ShowMessage('程式已在執行中,請勿重複啟動。');
    Application.Terminate;
    Exit;
  end;

  { 建立新的 Mutex,標記為首次啟動 }
  hMutex := CreateMutex(nil, False, NameMutex);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  { 釋放 Mutex 句柄 }
  if hMutex <> 0 then
    CloseHandle(hMutex);
end;

end.

專案檔(.dpr)最佳實作

將檢查邏輯放在專案檔的最前端,可避免後啟動的實例載入表單、初始化資源等無謂動作:

program Project1;

uses
  Forms, Windows,
  Unit1 in 'Unit1.pas' {Form1};

{$R *.res}

var
  hMutex: THandle;
const
  NameMutex = 'MyUniqueAppMutex';

begin
  { 主執行緒入口處檢查 }
  if OpenMutex(MUTEX_ALL_ACCESS, False, NameMutex) <> 0 then
  begin
    MessageBox(0, '程式已在執行中,請勿重複啟動。', '提示', MB_OK or MB_ICONINFORMATION);
    Exit;
  end;

  hMutex := CreateMutex(nil, False, NameMutex);

  Application.Initialize;
  Application.MainFormOnTaskbar := True;
  Application.CreateForm(TForm1, Form1);
  Application.Run;

  { 主執行緒出口釋放 }
  if hMutex <> 0 then
    CloseHandle(hMutex);
end.

重點提醒

  • Mutex 名稱需具唯一性,建議採用 GUID 或公司專屬前綴(如 Global\{CompanyName-AppName}),避免與其他程式衝突。
  • 若需在 Terminal Server 環境下跨 Session 生效,名稱前綴需加 Global\;僅限當前 Session 則用 Local\(預設)。
  • 務必在所有退出路徑(正常結束、異常終止)釋放句柄,防止核心物件洩漏。

掌握此技巧,即可輕鬆為 Delphi 應用程式加上「單一實例」保護,提升使用者體驗與系統資源利用率。

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