2012-03-25 13 views
7

Ho un file in cui sto scrivendo, ma ho bisogno di bloccarlo prima (usando flock()), per evitare che altri script scrivano su di esso. Così ho:Controlla se un file è già bloccato usando flock()?

$file=fopen($file_p); 

if (flock($file, LOCK_EX)) {//lock was successful 
    fwrite($file,$write_contents);   
} 

Ma ho bisogno di controllare se è già bloccato, per evitare che altri script di scrivere ad esso.

Come posso fare questo?

risposta

-1

vorrei controllare per vedere se non ho potuto ottenere un blocco sul file, come questo:

if (!flock($file, LOCK_EX)) { 
    throw new Exception(sprintf('Unable to obtain lock on file: %s', $file)); 
} 

fwrite($file, $write_contents); 
+1

Questo non è corretto. Se non si specifica la maschera di bit 'LOCK_NB' sull'operazione passata al flock, quindi * per impostazione predefinita, questa funzione verrà bloccata fino a quando non viene acquisito il blocco richiesto * ([source] (http://www.php.net// manuale/it/function.flock.php)). Con il codice di esempio che hai fornito, 'flock' non * restituirà * false per indicare che un blocco è stato eliminato sul file da un altro processo, ma semplicemente aspetterà che tale processo rilasci il suo blocco. –

+0

@MarkAmery: come? La logica è semplice, se non è possibile ottenere un 'lock esclusivo' sul file, quindi lanciare l'eccezione. Dipende dal codice chiamante per capire come gestire l'eccezione. –

+0

No - nel caso in cui il motivo per cui non è possibile acquisire il blocco è che un altro processo lo trattiene, il commento sopra non corrisponde a come si comporta il codice. Invece il comportamento del tuo codice è "Se non riesci a ottenere un blocco esclusivo sul file, continua ad aspettare finché puoi, quindi continua". - questo è il comportamento predefinito di 'flock'. Devi usare il modificatore 'LOCK_NB', come mostrato nella risposta di Ryan Y, per far sì che il tuo codice si comporti come descritto nel commento. –

-1

Il tuo gruppo di chiamata è il controllo per vedere se è già bloccato. Se è bloccato, che se() dichiarazione fallirebbe, quindi si può solo gettare un altro su di esso con qualcosa di simile:

if (flock($file, LOCK_EX)) {//lock was successful 
    fwrite($file,$write_contents); 
} else { 
    echo "$file is locked."; 
} 
+0

AHHH, quindi restituisce false se il file è già bloccato? –

+1

Questo non è corretto; guarda il mio commento sulla risposta piuttosto identica di Mike Purcell. –

14

Come descritto nel docs, utilizzare LOCK_NB per fare un tentativo di non-blocking per ottenere il blocco, e in caso di fallimento controllare l'argomento $wouldblock per vedere se qualcosa d'altro detiene il blocco.

if (!flock($fp, LOCK_EX|LOCK_NB, $wouldblock)) { 
    if ($wouldblock) { 
     // something already has a lock 
    } 
    else { 
     // couldn't lock for some other reason 
    } 
} 
else { 
    // lock obtained 
} 
Problemi correlati