2012-11-23 13 views
13

A seguito di questa answer per limitare una sola istanza di uno script php in esecuzione:Il file flock viene sbloccato quando il processo si interrompe in modo imprevisto?

<?php 

    $fp = fopen("/tmp/one.txt", "r+"); 
    if (flock($fp, LOCK_EX)) { 
    // 
    do_something_lengthy(); 
    // 
    flock($fp, LOCK_UN); 
    } else { 
    echo "Couldn't get the lock!"; 
    } 

    fclose($fp); 

?> 

La mia domanda è, sarà il 'ed flock one.txt file di essere sbloccare se il processo di morire nel mezzo della do_something_lengthy(), cioè prima chiamando lo flock($fp, LOCK_UN)?

+0

Questo dovrebbe essere abbastanza facile da testare. Inizia qualcosa di lungo corso, uccidilo e vedi cosa succede? – Brad

+0

Sì, certo. Se una risorsa permanente sopravvivrebbe al suo processo host, sarebbe un buco di sicurezza, dal momento che potrebbe essere utilizzato per eseguire il sistema anche come utente non privilegiato. – phihag

risposta

10

Secondo la pagina di manuale flock() che PHP utilizza internamente, un blocco viene rilasciato quando una flock() viene chiamato con LOCK_UN o quando il descrittore viene chiuso con fclose().

Al termine della scrittura, PHP o il sistema operativo chiudono i descrittori di file aperti, rilasciando in tal modo i blocchi che si possono avere.

A causa di detto comportamento this commit (5.3) e this one (5.2) è stato effettuato per non eseguire più lo sblocco in PHP stesso.

+0

In base alla pagina di manuale 'flock()' fclose() '(che viene eseguito al termine dello script) non sblocca il file dal php 5.3.2 –

+1

Non significa necessariamente che il file non sia sbloccato alla fine del processo; Farò alcuni test qui per vedere cosa succede. –

+0

Non intendevo che non venisse sbloccato, ma ho solo preso parti dal manuale.Ho fatto anche alcuni test e in effetti lo sblocco e fclose alla fine del processo –

2

Il blocco viene rilasciato automaticamente al termine dello script. Tuttavia, dovresti rilasciarlo manualmente e non affidarti all'avaria automatica. È meglio cogliere qualsiasi eccezione, gestirla e rilasciare il blocco. Vedere la documentazione regolamentazioni ufficiali - http://php.net/manual/en/function.flock.php

+3

+1. Ho avuto situazioni in cui a volte il sistema operativo non ha rilasciato il blocco –

+0

Timo - Stai dicendo che sei stato in grado di creare situazioni in cui il file era bloccato anche quando non c'erano processi in esecuzione che avevano un blocco esclusivo sul file? In tal caso, puoi fornire un esempio. –

4

Ho fatto questo piccolo script per provarlo

header('Content-type:text/plain; charset=utf-8'); 

$dir = dirname(__FILE__); 
$file = $dir.'/testflock.lock'; 
$fh = fopen($file, 'w+'); 

$unlocked = flock($fh, LOCK_EX | LOCK_NB); 
echo 'Locked: '.$file.' ';var_dump(!$unlocked);echo PHP_EOL; 
if($unlocked){ 
    sleep(10); 
    throw new Exception(); 
} 

e per me ci sono voluti il ​​sistema operativo per sbloccare il file circa 2-5 secondi dopo che lo script terminato l'esecuzione se non getta alcuna eccezione, e fino a 2-5 secondi dopo l'interruzione dello script a causa dell'eccezione generata.

Ricorda che dal php 5.3.2 fclose($fh) non sbloccherai il file, e il file rimarrà bloccato a meno che non lo sblocchi con php o dovrai aspettare che il SO lo sblocchi, cosa che potrebbe non accadere mai se c'è qualche bug (questo è successo a me)

per sbloccare il file:

flock($fh,LOCK_UN); 

per chiudere l'handle di file (sarà chiamato automaticamente quando lo script termina l'esecuzione)

fclose($fh); 

Se si blocca il file senza lo LOCK_NB, lo script attenderà che il file venga sbloccato.

+0

> questo mi è successo È possibile riprodurre –

Problemi correlati