Heim >Backend-Entwicklung >PHP-Problem >Was soll ich tun, wenn die Flock-PHP-Sperre fehlschlägt?
flock PHP-Sperrfehler wird dadurch verursacht, dass $file_lock nach dem Beenden der isRunning()-Methode nicht verwendet wird. Die Lösung besteht darin, sicherzustellen, dass das Dateihandle während des gesamten PHP-Lebenszyklus nicht freigegeben wird.
Die Betriebsumgebung dieses Artikels: Windows 7-System, PHP-Version 7.1, DELL G3-Computer
Was soll ich tun, wenn die PHP-Sperre fehlschlägt?
Lösung für das PHP-Flock-Fehlerproblem:
In den letzten zwei Tagen habe ich eine Methode für mein Nebenprojekt geschrieben, um die gleichzeitige Ausführung von PHP-Skripten zu vermeiden, die von crontab geplant werden.
So geht's
Im Allgemeinen sperrt dasselbe PHP-Skript dieselbe Festplattendatei nicht blockierend, wenn die Datei belegt ist, sodass das Skript dies tun kann sofort verlassen.
Phänomen
Aber in der Praxis hat sich herausgestellt, dass es möglich ist, direkt in der Controller-Datei zu flocken, aber wenn die Flock-Logik in eine Funktion in anderen Dateien gekapselt wird, wird sie ungültig.
Ursache
Nachdem ich lange debuggt hatte, fiel mir plötzlich ein, dass ich schon einmal auf diese Falle gestoßen war. .
Der Fehlercode lautet wie folgt:
class Crontab { /** * 确保任务没有并发执行 */ public static function isRunning() { global $argv; $ident = []; foreach ($argv as $idx => $value) { $ident[] = $idx . '=' . urlencode($value); } $ident = md5(implode('&', $ident)); $lockDir = \Yii::getAlias('@app/runtime/crontab/'); @mkdir($lockDir, 0755, true); $file_lock = fopen($lockDir . $ident, 'w+'); $wouldBlock = 0; flock($file_lock, LOCK_EX | LOCK_NB, $wouldBlock); return $wouldBlock; } }
class Crontab { /** * 确保任务没有并发执行 */ public static function isRunning() { global $argv; $ident = []; foreach ($argv as $idx => $value) { $ident[] = $idx . '=' . urlencode($value); } $ident = md5(implode('&', $ident)); $lockDir = \Yii::getAlias('@app/runtime/crontab/'); @mkdir($lockDir, 0755, true); $file_lock = fopen($lockDir . $ident, 'w+'); $wouldBlock = 0; flock($file_lock, LOCK_EX | LOCK_NB, $wouldBlock); return $wouldBlock; } }
Generieren Sie einen eindeutigen Hash-Wert basierend auf den Befehlszeilenparametern, der die PHP-Aufgabe darstellt.
Erstellen Sie eine Sperrdatei, führen Sie die nicht blockierende Flock-Sperre aus und geben Sie wouldBlock zurück, um festzustellen, ob die Sperre belegt ist.
Ich habe die Methode Crontab::isRunning() am Skripteintrag aufgerufen und festgestellt, dass nach gleichzeitigem Starten des Skripts die Sperre immer erhalten werden kann.
Der Grund für den Fehler ist: Nach dem Beenden der isRunning()-Methode wird $file_lock nicht mehr verwendet und ist ein von PHP gesammelter Müll. Das $fp-Dateihandle wird geschlossen, wodurch die Sperre automatisch aufgehoben wird.
Lösung
class Crontab { /** * 保存起来避免被php作为垃圾回收 * @var null */ static $file_lock = null; /** * 确保任务没有并发执行 */ public static function isRunning() { global $argv; $ident = []; foreach ($argv as $idx => $value) { $ident[] = $idx . '=' . urlencode($value); } $ident = md5(implode('&', $ident)); $lockDir = \Yii::getAlias('@app/runtime/crontab/'); @mkdir($lockDir, 0755, true); self::$file_lock = fopen($lockDir . $ident, 'w+'); $wouldBlock = 0; flock(self::$file_lock, LOCK_EX | LOCK_NB, $wouldBlock); return $wouldBlock; } }
class Crontab { /** * 保存起来避免被php作为垃圾回收 * @var null */ static $file_lock = null; /** * 确保任务没有并发执行 */ public static function isRunning() { global $argv; $ident = []; foreach ($argv as $idx => $value) { $ident[] = $idx . '=' . urlencode($value); } $ident = md5(implode('&', $ident)); $lockDir = \Yii::getAlias('@app/runtime/crontab/'); @mkdir($lockDir, 0755, true); self::$file_lock = fopen($lockDir . $ident, 'w+'); $wouldBlock = 0; flock(self::$file_lock, LOCK_EX | LOCK_NB, $wouldBlock); return $wouldBlock; } }
Stellen Sie einfach sicher, dass das Dateihandle während des gesamten PHP-Lebenszyklus nicht freigegeben wird, sodass es in der statischen Mitgliedsvariablen der Klasse gespeichert wird.
Empfohlenes Lernen: „PHP-Video-Tutorial“
Das obige ist der detaillierte Inhalt vonWas soll ich tun, wenn die Flock-PHP-Sperre fehlschlägt?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!