2011-09-18 55 views
6

我想實現一個簡單的例程使用信號量,這將允許我只運行應用程序的3個實例。我可以用3個互斥但這並不是一個很好的辦法我想這至今只允許使用信號量的應用程序的3個實例

var 
    hSem:THandle; 
begin 
    hSem := CreateSemaphore(nil,3,3,'MySemp3'); 
    if hSem = 0 then 
    begin 
    ShowMessage('Application can be run only 3 times at once'); 
    Halt(1); 
    end; 

我怎樣才能做到這正常嗎?

回答

16

請務必確保您釋放信號量,因爲如果您的應用程序死亡,這不會自動完成。

program Project72; 

{$APPTYPE CONSOLE} 

uses 
    Windows, 
    SysUtils; 

var 
    hSem: THandle; 

begin 
    try 
    hSem := CreateSemaphore(nil, 3, 3, 'C15F8F92-2620-4F3C-B8EA-A27285F870DC/myApp'); 
    Win32Check(hSem <> 0); 
    try 
     if WaitForSingleObject(hSem, 0) <> WAIT_OBJECT_0 then 
     Writeln('Cannot execute, 3 instances already running') 
     else begin 
     try 
      // place your code here 
      Writeln('Running, press Enter to stop ...'); 
      Readln; 
     finally ReleaseSemaphore(hSem, 1, nil); end; 
     end; 
    finally CloseHandle(hSem); end; 
    except 
    on E: Exception do 
     Writeln(E.ClassName, ': ', E.Message); 
    end; 
end. 
+0

偉大的編碼器,很好的答案。謝謝 ! – opc0de

+0

+1有點令人失望的是'SyncObjs.TSemaphore'不適合定時等待。或者我錯過了什麼。 –

+0

D2007甚至沒有SyncObjs.TSemaphore ...在XE中,您是正確的 - 可以在Linux中等待超時0,但不能在Windows上等待。愚蠢的 – gabr

2
  1. 你一定要嚐嚐,看它是否被創建
  2. 必須使用等待函數之一,看看你可以得到一個數
  3. 最後,你必須釋放鎖&處理,使其能夠工作在下次用戶關閉和打開應用

乾杯

var 
    hSem: THandle; 
begin 
    hSem := OpenSemaphore(nil, SEMAPHORE_ALL_ACCESS, True, 'MySemp3'); 
    if hSem = 0 then 
    hSem := CreateSemaphore(nil, 3, 3,'MySemp3'); 

    if hSem = 0 then 
    begin 
    ShowMessage('... show the error'); 
    Halt(1); 
    Exit;  
    end; 

    if WaitForSingleObject(hSem, 0) <> WAIT_OBJECT_0 then 
    begin 
    CloseHandle(hSem); 
    ShowMessage('Application can be runed only 3 times at once'); 
    Halt(1); 
    Exit; 
    end; 

    try 
    your application.run codes.. 

    finally 
    ReleaseSemaphore(hSem, 1, nil); 
    CloseHandle(hSem); 
    end; 
相關問題