2011-09-18 3 views
6

세마포어를 사용하여 간단한 루틴을 구현하려고합니다. 세마포어를 사용하면 응용 프로그램의 인스턴스를 세 개만 실행할 수 있습니다. 나는 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에서는 시간 초과를 기다릴 수 없습니다. Stupid – 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; 
관련 문제