Newsgroup: it.comp.lang.delphi
Titolo: Sincronizzazione risorza

Ciao ragazzi ho un problemino: devo sincronizzare 2 applicazioni che
accedono ad una risorza comune. Supponiamo che la risorza in questione
sia un lettore di smart card e le applicazioni Appl1 Appl2: ho bisogno
di qualcosa che blocchi Appl2 mentre cerca di accedere al lettore se
Appl1 lo ha occupato. Avevo pensato ai mutex, però da quanto ho letto
sull'help non mi sembra che questi vengano usati per la mutua
esclusione. Da quanto ne so(spero di sbagliarmi) due processi riescono
 a vedere solo questi(mutex)!?!
Qualche idea? Tra l'altro avevo pensato di sviluppare un
servizio(gestore) basato su socket che sincronizzasse l'accesso al
lettore ma ci sono dei seri problemi di sicurezza che me lo
impediscono.
Grazie in anticipo, sono nei casini..... HELP

  a vedere solo questi(mutex)!?!
Esistono molti modi per sincronizzare due applicazioni, diverse
tecniche IPC disponibili, tra cui mutex e semafori.  Dato che le
applicazioni sono distinte, è bene avere degli oggetti kernel
accedibili da entrambe.  L'unica informazione che entrambe devono
conoscere è il nome dell'oggetto kernel.
I mutex vengono spesso utilizzati per impedire, ad esempio, che si
avviino due istanze della stessa applicazione; l'applicazione quando
parte crea l'oggetto kernel, se ci riesce bene, altrimenti, se
l'errore incontrato è dovuto al fatto che un oggetto con quel nome già
esiste, allora vuol dire che esiste in memoria l'istanza
dell'applicazione che l'ha creato e quindi la seconda termina dando un
avviso all'utente.
E' solo un esempio, da cui puoi trarre spunto.

...

Ciao Andrea, ti riporto due righe dall'help riguardanti la CreateMutex
: 'The thread that owns a mutex can specify the same mutex in repeated
wait function calls without blocking its execution'.A me servirebbe
che si blocasse come un semaforo per poter usare la corrispettiva
'wait' e 'signal' dei Mutex(OpenMutex e ReleaseMutex ).Forse le ho
interpretate male queste due righe?
Ciao e grazie aspetto tue notizie.
P.S sono tre anni che leggo i tuoi post e francamente devo dire che
sei uno dei piu' preparati, ho imparato molto da te: grazie !

 interpretate male queste due righe?
Temo di sě ;-)  Sotto Windows su qualsiasi oggetto kernel puoi entrare
in attesa dello stato "segnalato", mutex compresi.
L'help dice, testualmente, che in fase di creazione di un mutex, č
necessario specificare l'ownership.
Lo stato di un mutex diventa "segnalato" quando non č piů "posseduto"
(owned) da alcun thread.
Con ReleaseMutex si forza il rilascio del mutex:
unit Unit1;
interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls,
Forms,
  Dialogs, StdCtrls;
type
  TForm1 = class(TForm)
    Button1: TButton;
    Label1: TLabel;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private declarations }
    FMutexHandle: THandle;
  public
  end;
var
  Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
  FMutexHandle := CreateMutex(nil, true, 'paperino');
  if (FMutexHandle <> 0 ) then
  begin
    if (GetLastError = ERROR_ALREADY_EXISTS) then
    begin
      if MessageDlg('risorsa bloccata, attendo ?', mtError,
                    [mbYes, mbNo], 0) = mrYes then
      begin
        Button1.Enabled := False;
        Label1.Caption := 'attesa rilascio risorsa per massimo 15
secondi...';
        Update;
        case WaitForSingleObject(FMutexHandle, 15000) of
          WAIT_TIMEOUT: begin
                          Button1.Enabled := True;
                          Label1.Caption := 'Timeout!';
                        end;
          WAIT_OBJECT_0: begin
                           ShowMessage('La risorsa č stata
sbloccata!');
                           Label1.Caption := '';
                         end;
        end;
      end;
    end
    else
    if GetLastError = 0 then
      Label1.Caption := 'mutex creato !'
    else
      Label1.Caption := Format('GetLastError = %d', [GetLastError])
  end
  else
    Label1.Caption := 'errore creazione mutex!';
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
  Label1.Caption := '';
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
  ReleaseMutex(FMutexHandle);
  Label1.Caption := 'Mutex rilasciato!';
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
  CloseHandle(FMutexHandle);
end;
end.

...

tutto ok sembra che funzionano. A presto