确保Linux上只有一个正在运行的PHP进程

我有一个PHP脚本从cron运行每分钟。 但有时它的工作时间超过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 (ie 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 

所以如果我有超过2行输出,我叫exit()

我想问:我是否正确? 或者,还有更好的方法?

任何帮助,将不胜感激

检查这种方式会创建一个竞争条件,其中两个进程可以同时检索列表,然后决定退出。 根据你想要做什么,这可能会也可能不会成为一个问题。

一个可能更好的选择是创建某种类型的锁。 我用过的一个简单的目录是只在进程运行时存在的目录mkdir是原子的,它会成功(没有其他进程正在运行)或失败(另一个进程已经创建它)。 请确保在完成时将其删除:

 if (!mkdir("lock_dir")) { echo "busy\n"; exit(); } register_shutdown_function(function() { rmdir("lock_dir"); }); 

或者更好的是,它看起来像是为了类似的目的而制作的。 这是手册中的例子:

 <?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); ?> 

只要按住脚本的运行时间,就和我的第一个例子类似。

最简单的方法是在进程启动时创建文件,并在最后删除它。 并检查文件是否存在,然后继续创建或死亡。

另一个是限制MaxClients的Apache为一(如果它是有效的选择在你的情况下)。