Я написал простую функцию, используемую для определения того, запущен ли уже скрипт, и предотвращения дублирования процессов:
class SomeClass{
public static function processLock($name)
{
$lockFile = "/tmp/" . $name;
$fp = fopen($lockFile, "w+");
if ($fp === false)
{
echo "Already running.\n";
exit;
}
else
{
if ( ! flock($fp, LOCK_EX | LOCK_NB))
{
echo "Already running.\n";
exit;
}
}
return $fp;
}
}
Затем я могу вызвать такую функцию вверху скрипта php:
Script_A:
<?
include_once "/SomeClass.php";
$lock = SomeClass::processLock("script_A_lock");
и это прекрасно работает ….. 99% времени. Однако иногда я обнаруживаю, что «script_A» не работает (он должен всегда работать).
Тогда я бегу lsof /tmp/script_A_lock
чтобы понять, почему «script_A» не запускается.
Результаты не имеют смысла! Я получаю что-то вроде этого:
COMMAND PID ......... NAME
Script_B 234 ......... script_A_lock
Несвязанный скрипт «script_B» как-то украл блокировку файла!
Так:
Этот подход я обычно использую для файла блокировки. Если файл не существует, создайте его, что означает, что процесс выполняется. Обязательно отсоедините его в конце.
#!/usr/bin/php
<?php
define('LOCK_FILE',__FILE__.'lock');
if (!is_file(LOCK_FILE)) {
touch(LOCK_FILE);
echo 'Do stuff'.PHP_EOL;
unlink(LOCK_FILE);
} else {
echo 'Lock file found'.PHP_EOL;
}
Функция flock предназначена для поддержки нескольких скриптов, обращающихся к одному файлу, она не предназначена для использования в качестве файла блокировки. http://php.net/manual/en/function.flock.php
Других решений пока нет …