Я знаю, что это старый вопрос, но есть подход, который ранее не упоминался, и который, я думаю, стоит рассмотреть.
Одна из проблем, связанных с решением для файла блокировки или флага базы данных, как уже упоминалось, заключается в том, что если скрипт завершится неудачей по какой-либо причине, отличной от нормального завершения, он не снимет блокировку. И поэтому следующий экземпляр не запустится, пока блокировка не будет очищена вручную или очищена с помощью функции очистки.
Если, однако, вы уверены, что скрипт должен запускаться только один раз, то из скрипта относительно легко проверить, запущен ли он уже при запуске. Вот некоторый код:
function checkrun() {
exec("ps auxww",$ps);
$r = 0;
foreach ($ps as $p) {
if (strpos($p,basename(__FILE__))) {
$r++;
if ($r > 1) {
echo "too many instances, exiting\n";
exit();
}
}
}
}
Просто вызовите эту функцию в начале сценария, прежде чем делать что-либо еще (например, открыть обработчик базы данных или обработать файл импорта), и если тот же сценарий уже запущен, то он появится дважды в списке процессов - один раз для предыдущего экземпляра и один раз для этого. Так что, если он появляется более одного раза, просто выйдите.
Здесь есть потенциальная ошибка: я предполагаю, что у вас никогда не будет двух сценариев с одинаковым базовым именем, которые могут законно запускаться одновременно (например, один и тот же сценарий, запущенный под двумя разными пользователями). Если это возможно, вам нужно расширить проверку на что-то более сложное, чем простая подстрока в базовом имени файла. Но это работает достаточно хорошо, если у вас есть уникальные имена файлов для ваших скриптов.