我有每分钟从cron运行的php脚本。但有时会超过1分钟。我的问题是:确保现在仅运行一个进程的最佳方法是什么?
我使用以下代码:
$output = shell_exec('ps aux | grep some_script.php | grep -v grep'); //get all processes containing "some_script.php" and exclude current grep process
$trimmed = rtrim($output, PHP_EOL); //trim newline symbol in the end
$processes = explode(PHP_EOL, $trimmed); //get the array of lines (i.e. processes)
$procCnt = count($processes); //get number of lines
if ($procCnt > 2) {
echo "busy\n";
exit(); //exit if number of processes more than 2 (see explaination below)
}
如果从cron运行一个some_script进程,则shell_exec返回类似以下内容:
apache 13593 0.0 0.0 9228 1068 ? Ss 18:20 0:00 /bin/bash -c php -f /srv/www/robot/some_script.php 2>&1
apache 13602 0.0 0.0 290640 10544 ? S 18:20 0:00 php -f /srv/www/robot/some_script.php
所以如果我的输出中有两行以上,我会调用exit()
我想问:我走对了吗?或者,还有更好的方法?
任何帮助,将不胜感激
检查这种方式会创建一个竞争条件,其中两个进程可以同时检索列表,然后两个都决定退出。根据您要执行的操作,这可能是问题,也可能不是问题。
一个更好的替代方法是创建某种类型的锁。我使用的一个简单目录是仅在进程运行时才存在的目录-mkdir
是原子的,它将成功(没有其他进程在运行)或失败(另一个进程已经创建了该目录)。只要确保在完成后将其删除即可:
if (!mkdir("lock_dir")) {
echo "busy\n";
exit();
}
register_shutdown_function(function() {
rmdir("lock_dir");
});
或者更好的是,它看起来flock
是出于类似的目的。这是手册中的示例:
<?php
$fp = fopen("/tmp/lock.txt", "r+");
if (flock($fp, LOCK_EX)) { // acquire an exclusive lock
ftruncate($fp, 0); // truncate file
fwrite($fp, "Write something here\n");
fflush($fp); // flush output before releasing the lock
flock($fp, LOCK_UN); // release the lock
} else {
echo "Couldn't get the lock!";
}
fclose($fp);
?>
只需按住脚本运行时的锁即可,类似于我的第一个示例。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句