程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Delphi >> 多線程編程(11) - 多線程同步之Mutex(互斥對象)[續]

多線程編程(11) - 多線程同步之Mutex(互斥對象)[續]

編輯:Delphi

Mutex 作為系統核心對象是可以跨進程的(臨界區就不行), 我們可以利用互斥對象禁止程序重復啟動.

工作思路:

先用 OpenMutex 嘗試打開一個自定義名稱的 Mutex 對象, 如果打開失敗說明之前沒有這個對象存在;

如果之前沒有這個對象, 馬上用 CreateMutex 建立一個, 此時的程序應該是第一次啟動;

再重復啟動時, 那個 OpenMutex 就有結果了, 然後強制退出.

最後在程序結束時用 CloseHandle 釋放 Mutex 對象.

function OpenMutex(
 dwDesiredAccess: DWORD; {打開權限}
 bInheritHandle: BOOL;  {能否被當前程序創建的進程繼承}
 pName: PWideChar    {Mutex 對象的名稱}
): THandle; stdcall;   {成功返回 Mutex 的句柄; 失敗返回 0}

注意, 這裡的 CreateMutex 函數應該有個名了, 因為 OpenMutex 要用到;

另外, CreateMutex 的第二個參數已經不重要了(也就是 True 和 False 都行), 因為這裡是用其名稱來判斷的.

程序可以這樣寫: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 = 'MyMutex';
procedure TForm1.FormCreate(Sender: TObject);
begin
 if OpenMutex(MUTEX_ALL_ACCESS, False, NameMutex) <> 0 then
 begin
  ShowMessage('該程序已啟動');
  Application.Terminate;
 end;
 hMutex := CreateMutex(nil, False, NameMutex);
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
 CloseHandle(hMutex);
end;
end.

這一般都是寫在 dpr 主程序裡, 省得讓後啟動的程序執行些無用的代碼:program Project1;
uses
 Forms, Windows,
 Unit1 in 'Unit1.pas' {Form1};
{$R *.res}
var
 hMutex: THandle;
const
 NameMutex = 'MyMutex';
begin
 {主線程入口}
 if OpenMutex(MUTEX_ALL_ACCESS, False, NameMutex) <> 0 then
 begin
  MessageBox(0, '該程序已啟動', '提示', MB_OK);
  Application.Terminate;
 end;
 hMutex := CreateMutex(nil, False, NameMutex);
 Application.Initialize;
 Application.MainFormOnTaskbar := True;
 Application.CreateForm(TForm1, Form1);
 Application.Run;
 CloseHandle(hMutex);
 {主線程出口}
end.

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