我见过一个PHP代码,它使用shell命令来确定此进程是否正在运行,但我已经丢失了。你能给我一个如何做到这一点的提示吗?
想法是创建一个php文件,并使用 php -f 将此文件作为cron作业运行。脚本的执行时间可能是10秒,但也可能是10分钟。我需要让这个cron每分钟运行一次,如果来自流行分钟的cron仍在运行 - 停止新的cron并让另一个完成。
我在shell编程方面不是很好,所以我需要一些帮助。
P.S 这个想法是创建一个守护进程而不在后台放置无休止的PHP进程。
答案 0 :(得分:3)
您应该尝试获取锁定文件上的独占非阻塞锁定。如果成功,您的进程是唯一正在运行的实例,您应该保持锁定直到您终止。如果你没有成功获得锁,那么已经有另一个正在运行的实例,你应该终止。
答案 1 :(得分:2)
出于多种目的,以下代码是可以的(可能存在竞争条件,但对于微小的cronjob,这可能非常罕见):
if (file_exists($lockfilename)) {
... // lock is already taken
} else {
if ( !file_put_contents($lockfilename, $lockstring)) {
error("unable to write $lockfilename");
}
$lock_taken = true;
... // do what you have to do
if ( !unlink($lockfilename)) {
warning("unable to unlink $lockfilename");
}
$lock_taken = false;
}
全局变量$lock_taken
可能有助于确保在执行暂停时删除lockfile。 $lockstring
可以是日期或Unix时间戳,如果它显然太旧(但filemtime()
就足够了),这可能对删除锁有用。
如果你绝对不能冒险参加比赛,你必须做一些像
这样的事情if ( !($lockfile = fopen($lockfilename, "x"))) {
... // lock is already taken
} else {
$lock_taken = true;
... // write something to lockfile (optional)
fclose($lockfile);
... // do what you have to do
if ( !unlink($lockfilename)) {
warning("unable to unlink $lockfilename");
}
$lock_taken = false;
}
但这仅适用于本地锁定文件。
答案 2 :(得分:1)
独占文件锁定方法优于“检查文件是否存在”,因为如果脚本在删除文件之前崩溃,则锁定仍然存在。
以下是文件锁定的代码:
//Allow only one instance
$fileHandler = fopen('file_lock.lock', 'w');
$hasLock = flock($fileHandler, LOCK_EX | LOCK_NB);
if (!$hasLock)
die("Another instance is already running");
//do work
//release lock
flock($fileHandler, LOCK_UN);
fclose($fileHandler);
释放锁定块是可选的,因为系统将在脚本执行后自动释放锁定。