2012-11-23 7 views
13

Nach dieser answer nur eine Instanz eines PHP-Skript laufen zu begrenzen:Wird die beflockte Datei freigegeben, wenn der Prozess unerwartet abbricht?

<?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); 

?> 

Meine Frage ist, wird die flock ‚ed eins.txt Datei entsperren, wenn der Prozess in der Mitte des do_something_lengthy() sterben, dh vor rufen flock($fp, LOCK_UN)?

+0

Dies sollte einfach genug sein, um zu testen. Beginne etwas, das lange läuft, töte es und schau was passiert? – Brad

+0

Ja, natürlich. Wenn eine permanente Ressource ihren Host-Prozess überleben würde, wäre das eine Sicherheitslücke, da sie das System sogar als unprivilegierter Benutzer verwenden könnte. – phihag

Antwort

10

Laut Handbuch Seite von flock(), die PHP intern verwendet, wird eine Sperre freigegeben, wenn entweder flock() mit LOCK_UN genannt wird, oder wenn der Deskriptor geschlossen wird mit fclose().

Nach Beendigung des Skripts schließt entweder PHP oder das Betriebssystem die geöffneten Dateideskriptoren und gibt dadurch die Sperren frei, die Sie möglicherweise haben.

Aufgrund dieses Verhaltens this commit (5.3) und this one (5.2) wurde nicht mehr die Entsperrung in PHP selbst gemacht.

+0

Entsprechend der 'flock()' Handbuchseite 'fclose()' (die ausgeführt wird, wenn das Skript beendet wird), wird die Datei seit php 5.3.2 nicht freigegeben –

+1

Bedeutet nicht notwendigerweise, dass die Datei am Ende nicht entsperrt wird des Prozesses; Ich werde hier einige Tests durchführen, um zu sehen, was passiert. –

+0

Ich meinte nicht, dass es nicht entsperrt wird, nahm nur Teile aus dem Handbuch.Ich habe auch ein paar Tests gemacht, und tatsächlich öffnet und schließt es am Ende des Prozesses –

2

Die Sperre wird automatisch aufgehoben, wenn das Skript beendet ist. Sie sollten es jedoch manuell freigeben und sich nicht darauf verlassen, dass ein automatischer Fehler auftritt. Besser, irgendeine Ausnahme zu fangen, sie zu behandeln und die Sperre aufzuheben. Sehen Sie sich die offiziellen Dokumente - http://php.net/manual/en/function.flock.php

+3

+1. Ich hatte Situationen, in denen das OS manchmal die Sperre nicht freigab –

+0

Timo - Sagst du, dass du Situationen erstellen konntest, in denen die Datei gesperrt wurde, selbst wenn keine Prozesse ausgeführt wurden, die eine exklusive Sperre für die Datei hatten? Wenn ja, können Sie ein Beispiel geben. –

4

Ich habe dieses kleine Skript es

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(); 
} 

zu testen und für mich dauerte es das Betriebssystem die Datei ca. 2-5 Sekunden zu entsperren, nachdem das Skript ausgeführt wird beendet, wenn es keine Ausnahme wirft, und bis zu 2-5 Sekunden nach dem Stoppen des Skripts wegen der ausgelösten Exception.

Denken Sie daran, dass ab php 5.3.2 fclose($fh) wird nicht die Datei entsperren, und die Datei bleibt gesperrt, es sei denn, Sie entsperren es mit PHP oder Sie müssen warten, bis das Betriebssystem es entsperren, die möglicherweise nie passieren wenn es einige Fehler ist (dies mir passiert)

um die Datei zu entsperren:

flock($fh,LOCK_UN); 

um den Datei-Handle zu schließen (wird automatisch aufgerufen, wenn das Skript ausgeführt wurde)

fclose($fh); 

Wenn Sie die Datei ohne die Datei LOCK_NB sperren, wartet das Skript darauf, dass die Datei entsperrt wird.

+0

> das ist mir passiert Ist es möglich zu reproduzieren –

Verwandte Themen