Wie kann verhindert werden, dass PHP-Skript mehr als einmal ausgeführt wird?

8

Ich habe gerade versucht zu verhindern, dass ein Skript onlytask.php mehr als einmal ausgeführt wird:

%Vor%

und es gibt einen Cron-Job, um das obige Skript jede Minute auszuführen:

%Vor%

Es funktioniert eine Weile. Nach ein paar Tagen, wenn ich das tue:

%Vor%

Ich habe festgestellt, dass zwei Instanzen laufen! Nicht drei oder mehr, nicht eins. Ich habe eine der Instanzen getötet. Nach ein paar Tagen gibt es wieder zwei Instanzen.

Was ist falsch im Code? Gibt es andere Alternativen, um nur eine Instanz der onlytask.php zu begrenzen?

ps. Mein /tmp/ Ordner ist nicht bereinigt. ls -al /tmp/*.lock zeigt an, dass die Sperrdatei am ersten Tag erstellt wurde:

%Vor%     
ohho 12.12.2012, 09:10
quelle

6 Antworten

3

Nun überprüfe ich, ob der Prozess von ps ausgeführt wird und das PHP-Skript um ein bash script verwerfen:

%Vor%

und führen Sie das Skript bash pro Minute cron aus.

    
ohho 18.12.2012, 06:24
quelle
7

Sie sollten x flag beim Öffnen der Sperrdatei verwenden:

%Vor%

Hinweis aus dem PHP-Handbuch

  

' x ' - Erstellt und öffnet nur zum Schreiben; Platziere den Dateizeiger an der   Anfang der Datei. Wenn die Datei bereits existiert, rufen Sie den Aufruf fopen () auf   wird fehlschlagen, indem FALSE zurückgegeben wird und ein Fehler der Ebene generiert wird   E_WARNUNG. Wenn die Datei nicht existiert, versuchen Sie, sie zu erstellen. Das ist   entspricht der Angabe von O_EXCL | O_CREAT Flags für das Underlying   Öffnen Sie (2) Systemaufruf.

Und hier ist O_EXCL Erklärung von man-Seite :

  

O_EXCL - Wenn O_CREAT und O_EXCL gesetzt sind, wird open () bei der Datei fehlschlagen   existiert. Die Überprüfung auf das Vorhandensein der Datei und die Erstellung von   die Datei, wenn sie nicht existiert sollte atom in Bezug auf andere sein   Threads, die open () ausführen und denselben Dateinamen in demselben Namen benennen   Verzeichnis mit O_EXCL und O_CREAT gesetzt. Wenn O_EXCL und O_CREAT gesetzt sind,   und Pfadnamen ein symbolischer Link, open () soll fehlschlagen und errno auf setzen   [EEXIST], unabhängig vom Inhalt des symbolischen Links. Wenn O_EXCL   ist gesetzt und O_CREAT ist nicht gesetzt, das Ergebnis ist undefiniert.

AKTUALISIEREN :

Zuverlässigerer Ansatz - Führe das Hauptskript aus, das die Sperre erwirbt, das Arbeiterscript ausführt und die Sperre freigibt.

%Vor%

Hier geht der Arbeiter. Lassen Sie uns einen gefälschten fatalen Fehler aufwerfen:

%Vor%

Hier ist der Output, den ich bekommen habe:

%Vor%

Der Hauptpunkt ist, dass die Sperrdatei richtig bereinigt ist, damit Sie main.php erneut ohne Probleme ausführen können.

    
galymzhan 12.12.2012 09:53
quelle
1
%Vor%

Sie können eine zusätzliche Überprüfung hinzufügen, indem Sie die PID schreiben und dann in der file_exist-Anweisung überprüfen. Um es noch sicherer zu machen, können Sie alle laufenden Anwendungen per "ps fax" Ende prüfen, ob diese Datei in der Liste ist.

    
Niclas Larsson 12.12.2012 09:12
quelle
0

Versuchen Sie, das Vorhandensein der Datei und nicht ihre Bestandsflagge zu verwenden:

%Vor%     
k1dbl4ck 12.12.2012 09:16
quelle
0

Sie können Sperrdateien verwenden, wie einige vorgeschlagen haben, aber was Sie wirklich suchen, ist das PHP Semaphore Funktionen. Diese sind wie Dateisperren, aber speziell für das, was Sie tun, um den Zugriff auf freigegebene Ressourcen zu beschränken.

    
Jordan Mack 28.12.2012 01:06
quelle
0

Verwenden Sie niemals die Verknüpfung für Sperrdateien oder andere Funktionen wie Umbenennen. Es brich dein LOCK_EX unter Linux. Zum Beispiel, nach dem Aufheben der Verknüpfung oder Umbenennen der Sperrdatei, jedes andere Skript wird immer von flock () wahr.

Der beste Weg, um ein vorheriges gültiges Ende zu erkennen - schreiben Sie, um einige Bytes in der Endsperre zu sperren, bevor LOCK_UN behandelt wird. Und nach LOCK_EX lesen Sie einige Bytes aus Lock-Dateien und ftruncate Handle.

Wichtiger Hinweis: Alles getestet auf PHP 5.4.17 unter Linux und 5.4.22 unter Windows 7.

Beispielcode:

setze Semaphor:

%Vor%

leave semaphore (besserer Aufruf im Shutdown-Handler):

%Vor%     
Enyby 04.01.2014 20:22
quelle

Tags und Links