Concorrenza per l'accesso a un file e mutua esclusione a semaforo
In PHP bisogna tener presente il fatto che il file presente sul server è condiviso fra tutti i visitatori del sito. Questa situazione in informatica viene detta concorrenza e si verifica ogni qual volta si hanno più processi che concorrono per l'utilizzo della stessa risorsa. Un esempio di concorrenza (non associata ai file) si verifica quando una stessa stampante è condivisa da più computer e ci sono più processi di stampa avviati contemporaneamente.
Nel caso dei file in PHP la concorrenza è particolarmente pericolosa in fase di scrittura su file. Cosa accade infatti se più processi provano a scrivere lo stesso file contemporaneamente? Quale copia del file viene salvata alla fine? Si pensi per esempio a un file contenente le prenotazioni dei posti su un aereo. E' possibile che lo stesso posto venga prenotato contemporaneamente da due viaggiatori diversi, i quali accedono allo stesso file nello stesso momento, modificandolo insieme.
La soluzione a questo problema si ottiene facendo in modo che il primo processo che cerca di accedere a un file lo blocchi per tutto il tempo necessario a svolgere le proprie operazioni. Alla fine delle operazioni il processo sbloccherà il file, rendendolo nuovamente accessibile agli altri. Nel frattempo, mentre un file è bloccato, tutti gli altri processi concorrenti verranno messi in uno stato di attesa (attendono che si liberi la risorsa bloccata). Questo meccanismo in informatica è noto come mutua esclusione a semaforo, perchè funziona analogamente a un semaforo che blocca l'accesso a un incrocio da parte di tutte le strade tranne una.
In PHP la mutua esclusione a semaforo viene implementata mediante la funzione flock. La sintassi di questa funzione è:
flock(puntatore_a_file, modo);
Il modo è rappresentato da una costante predefinita che può assumere uno dei seguenti valori:
Si consideri il seguente esempio di file, aperto in scrittura, e bloccato con la flock:
<?php
$punt = fopen ("prenotazione aeree", "w");
flock($punt, LOCK_EX);
fwrite($punt,$prenotazione);
flock($punt, LOCK_UN);
fclose($punt);
?>
Si osservi con attenzione la sequenza delle istruzioni:
Sito realizzato in base al
template offerto da
http://www.graphixmania.it