2011-09-18 20 views
6

Tôi đang cố gắng thực hiện một thói quen đơn giản bằng cách sử dụng các ẩn dụ cho phép tôi chỉ chạy 3 phiên bản của ứng dụng. Tôi có thể sử dụng 3 mutexes nhưng đó không phải là một cách tiếp cận tốt đẹp tôi đã cố gắng này cho đến nayChỉ cho phép 3 trường hợp của một ứng dụng bằng cách sử dụng các semaphores

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; 

Làm thế nào tôi có thể làm điều này đúng?

Trả lời

16

Luôn đảm bảo rằng bạn phát hành một semaphore vì điều này không được thực hiện tự động nếu ứng dụng của bạn chết.

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

Trình lập trình tuyệt vời, câu trả lời tuyệt vời. Cảm ơn ! – opc0de

+0

+1 Hơi thất vọng khi 'SyncObjs.TSemaphore' không phục vụ cho thời gian chờ đợi. Hay tôi đã bỏ lỡ điều gì đó. –

+0

D2007 thậm chí không có SyncObjs.TSemaphore ... Trong XE, bạn chính xác - người ta có thể chờ với thời gian chờ 0 trong Linux nhưng không phải trên Windows. Ngu ngốc – gabr

2
  1. Bạn phải cố gắng để xem nếu nó đã được tạo ra
  2. Bạn phải sử dụng một trong những chức năng chờ đợi để xem nếu bạn có thể nhận được một số
  3. Cuối cùng, bạn phải phát hành các khóa & xử lý sao cho nó có thể làm việc cho người sử dụng thời gian gần tới và mở ứng dụng của bạn

Cheers

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; 
Các vấn đề liên quan