2011-09-18 8 views
6

Estoy tratando de implementar una rutina simple usando semáforos que me permitan ejecutar solo 3 instancias de la aplicación. Podría utilizar 3 mutex pero eso no es un buen enfoque he intentado esto hasta ahoraPermitir solo 3 instancias de una aplicación usando semáforos

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; 

¿Cómo puedo hacer esto correctamente?

Respuesta

16

Siempre asegúrese de liberar un semáforo porque esto no se hace automáticamente si su aplicación muere.

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

Gran codificador, excelente respuesta. Gracias ! – opc0de

+0

+1 Un poco decepcionante que 'SyncObjs.TSemaphore' no satisfaga las esperas temporizadas. O me perdí algo. –

+0

D2007 ni siquiera tiene SyncObjs.TSemaphore ... En XE, tiene razón: uno puede esperar con el tiempo de espera 0 en Linux pero no en Windows. Estúpido – gabr

2
  1. Usted debe tratar de ver si se creó
  2. Debe utilizar una de las funciones de espera para ver si puede obtener un recuento
  3. Al final, debe liberar el bloqueo & manejar de modo que pueda funcionar la próxima vez que el usuario cierra y abre su aplicación

Saludos

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; 
Cuestiones relacionadas