Основываясь на комментариях здесь и моих собственных наблюдениях, я составил список «за» и «против» обоих подходов:
flock
метод:
плюсы:
- Больше совместимо с операционными системами
- Знание bash не требуется
- Более распространенный подход, много примеров
- Работает даже при
exec()
отключено
- Может использовать несколько блокировок в одном файле, чтобы разрешить разные "режимы" для одного и того же файла одновременно
минусы:
- Это не определенно. Если ваш файл блокировки удален внешним процессом / пользователем, вы можете получить несколько процессов. Если вы сохраняете файл блокировки в каталоге
/tmp
, это допустимая возможность, поскольку все в этом каталоге должно быть «временным»
- При определенных обстоятельствах, когда процесс неожиданно умирает, блокировка файла может быть перенесена на несвязанный процесс (сначала я не поверил, но обнаружил, что это происходит (хотя и редко) в более чем 200 системах на основе Unix). , в 3 разных операционных системах)
exec("ps -C...")
метод
плюсы:
- Поскольку вы фактически считаете процессы , он будет работать каждый раз, независимо от состояния блокировки файлов и т. Д.
минусы:
- Работает только в Linux
- требует, чтобы "exec" был включен
- Если вы измените имя своего скрипта, это может привести к двойным процессам (и убедиться, что имя вашего скрипта не жестко запрограммировано в коде)
- Предполагается, что ваш скрипт имеет только один запущенный "режим"
РЕДАКТИРОВАТЬ: я закончил с помощью этого:
if (exec("pgrep -x " . $scriptName . " -u ". $currentUser . " | wc -l") > 1)
{
echo $scriptName . " is already running.\n";
exit;
}
... потому что ps
не позволяет фильтровать владельца процесса в дополнение к имени процесса, и я хотел, чтобы этот сценарий запускался несколько раз, если его запускал другой пользователь.
РЕДАКТИРОВАТЬ 2:
... Итак, после нескольких дней работы он тоже не идеален. Каким-то образом процесс запускался несколько раз на одном компьютере под одним и тем же пользователем. Я могу только предположить, что была какая-то проблема (не хватило памяти и т. Д.), Из-за которой pgrep
ничего не возвращал, когда он должен был что-то возвращать.
Таким образом, это означает, что НИКОГДА метод flock
и методы подсчета не являются на 100% надежными. Вам нужно будет определить, какой подход будет работать лучше для вашего проекта.
В конечном счете, я использую другое решение, которое хранит PID текущей задачи в файле блокировки, которое на самом деле не заблокировано с помощью flock. Затем, когда скрипт запускается, проверяет, существует ли файл блокировки, и, если он есть, получает содержимое (PID последнего запуска скрипта). Затем он проверяет, все ли еще выполняется, сравнивая содержимое /proc/#PID#/cmdline
. с именем запущенного скрипта.