Использование блокировки файлов для обеспечения того, чтобы скрипт PHP Daemon запускался только один раз - PullRequest
0 голосов
/ 11 января 2019

Я написал простую функцию, используемую для определения того, запущен ли уже сценарий и предотвращения дублирования процессов:

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" каким-то образом украл блокировку файла!

Итак:

  1. Как это происходит? Слово «script_A_lock» ТОЛЬКО появляется в Script_A (я искал весь проект), а Script_A НИКОГДА не включен.
  2. Как я могу предотвратить это? Очевидно, что только скрипт A должен содержать «script_A_lock».

1 Ответ

0 голосов
/ 11 января 2019

Это подход, который я обычно использую для файла блокировки. Если файл не существует, создайте его, что означает, что процесс выполняется. Обязательно отсоедините его в конце.

#!/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

...