【发布时间】:2012-11-29 22:52:54
【问题描述】:
目前,我试图阻止onlytask.php 脚本多次运行:
$fp = fopen("/tmp/"."onlyme.lock", "a+");
if (flock($fp, LOCK_EX | LOCK_NB)) {
echo "task started\n";
//
while (true) {
// do something lengthy
sleep(10);
}
//
flock($fp, LOCK_UN);
} else {
echo "task already running\n";
}
fclose($fp);
并且有一个cron作业每分钟执行一次上述脚本:
* * * * * php /usr/local/src/onlytask.php
它工作了一段时间。几天后,当我这样做时:
ps auxwww | grep onlytask
我发现有 两个 实例正在运行!不是三个或更多,不是一个。我杀死了其中一个个体。几天后,又有两个实例。
代码有什么问题?还有其他替代方法可以限制 onlytask.php 的一个实例正在运行吗?
附言我的/tmp/ 文件夹未清理。 ls -al /tmp/*.lock 显示锁定文件是在第一天创建的:
-rw-r--r-- 1 root root 0 Dec 4 04:03 onlyme.lock
【问题讨论】:
-
非常有趣,但似乎这应该是正确的......你的代码框架就是这样吗?我确实想知道如果通过
false而不是资源会发生什么。当然它返回false。如果不这样做,那将是非常非常奇怪的,但我已经看到 PHP 做出了一些非常奇怪的选择。此外,flock 的内部可能存在缺陷(或者使用的系统调用——尽管这在很久以前就已经被注意到了)。 -
代码几乎 100% 像真实代码。
// do something lengthy实际上是exec()另一个 .php 是应该定期运行的脚本,但不超过一次。 -
第二个进程将等待第一个进程完成。见错误:stackoverflow.com/questions/5524073/lock-nb-ignored