gpt4 book ai didi

php - 为什么在 PHP 中使用 "lock"文件而不是仅仅计算进程数?

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:43:17 24 4
gpt4 key购买 nike

我见过很多使用“锁定”文件来跟踪 PHP 脚本当前是否正在运行的示例。

例子:

  1. 脚本开始
  2. 检查“/tmp/lockfile”当前是否被锁定
  3. 如果它被锁定,退出。如果没有,锁定文件并继续

这样,如果长时间运行的脚本启动两次,则只有第一个实例会运行。这很棒。

但是,绕过它似乎是错误的方法。为什么我们不像这样检查进程是否已经在运行?

if(exec("ps -C " . basename(__FILE__) . " --no-headers | wc -l") > 1){
echo "Already running.";
exit;
}

这种方法有什么潜在的缺陷吗?为什么我经常看到“锁定”文件解决方法?用我们正在寻找的名称来计算进程显然更准确....

最佳答案

根据此处的评论和我自己的观察,我列出了两种方法的优缺点:

flock 方法:

优点:

  • 跨操作系统的兼容性更好
  • 无需 bash 知识
  • 更常见的方法,很多例子
  • 即使禁用 exec() 也能工作
  • 可以在单个文件中使用多个锁以允许同一文件同时以不同的“模式”运行

缺点:

  • 不确定。如果您的锁定文件被外部进程/用户删除,您最终可能会遇到多个进程。如果您将锁定文件保存在 /tmp 目录中,这是一种有效的可能性,因为该目录中的所有内容都应该是“临时的”
  • 在某些情况下,当一个进程意外终止时,文件锁可以转移到一个不相关的进程(起初我不相信这一点,但我发现它发生在 200 多个基于 unix 的系统上(尽管很少) , 在 3 种不同的操作系统中)

exec("ps -C...") 方法

优点:

  • 由于您实际上是在计算进程数,因此无论文件锁定状态等如何,它每次都会起作用。

缺点:

  • 只适用于 linux
  • 需要启用“exec”
  • 如果您更改脚本的名称,可能会导致双重进程(并确保您的脚本名称未硬编码在代码中)
  • 假设您的脚本只有一个运行“模式”

编辑:我最终使用了这个:

if (exec("pgrep -x " . $scriptName . " -u ". $currentUser . " | wc -l") > 1)
{
echo $scriptName . " is already running.\n";
exit;
}

... 因为 ps 不允许您过滤除进程名称之外的进程所有者,并且我希望允许此脚本在不同用户的情况下运行多次正在运行它。


编辑 2:

... 所以,在运行了几天之后,它也不完美。不知何故,该进程在同一用户下的同一台机器上多次启动。我唯一的猜测是存在一些问题(内存不足等)导致 pgrep 什么都没有返回,而它应该返回一些东西。

所以这意味着 flock 方法和计数过程方法都不是 100% 可靠的。您必须确定哪种方法更适合您的项目。

最终,我使用了另一种解决方案,将当前任务的 PID 存储在“锁定”文件中,实际上并没有被 flock 锁定。然后,当脚本启动时,检查锁定文件是否存在,如果存在,则获取内容(脚本上次启动的 PID)然后,它通过比较 /检查它是否仍在运行proc/#PID#/cmdline 包含正在运行的脚本名称的内容。

关于php - 为什么在 PHP 中使用 "lock"文件而不是仅仅计算进程数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54246654/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com