停止 cron 触发进程的并行处理

停止 cron 触发进程的并行处理

我已经将我的网络服务器 cron 作业配置为每 15 分钟触发一些 PHP 脚本,但有时当同一脚本的另一个进程启动时,该脚本需要超过 15 分钟才能完成执行。这给我们的逻辑带来了问题。我只想运行同一进程的一个实例,如果它完成,则只让另一个进程执行(不想将进程放入队列中,只需在那一刻终止并在下一个时间间隔执行)。

示例:我有三个 PHP 文件,网络服务器 cron 作业每 15 分钟就会调用一次。假设a.php、b.php、c.php。该脚本可能需要 15 分钟以上才能完成执行。在执行结束时,它会更新我们的数据库,因此无法运行同一脚本文件的两个副本(这将破坏我们的逻辑)。就像说 a.php 在下午 4 点触发,然后在下午 4 点 15 分,cron 将再次触发 a.php。这里我想检查a.php是否已完成执行,如果没有则跳过调用并通过检查相同的情况在下午4.30触发它,但b.php,c.php和a.php是并行运行的(但相同的实例可以't)。

答案1

标准做法是使用 pid 文件。每次执行脚本时,让它检查文件以查看它是否已在某处运行。操作顺序概述如下。

  • 读取 pid/var/run/yourscriptname.pid
  • 检查pid是否正在运行,如果是则退出
  • 获取你的pid,将其写入/var/run/yourscriptname.pid
  • 正常执行
  • 删除pid文件

在您的情况下,这可以做到,但在某些情况下,脚本的调用速度可能足够快,以至于在检查 pid 和写入 pidfile 之间的时间内,另一个进程启动,也看不到 pidfile 并继续执行。您可以通过使用建议锁定进一步收紧事情。它是操作系统在几乎所有 Unix 上提供的功能。

参考:

答案2

这非常简单,通过flock

* * * * * /usr/bin/flock -n /tmp/fcj.lockfile /usr/local/bin/frequent_cron_job

归功于这个答案。我是通过谷歌来到这里的,所以我也想在这里分享一下。

答案3

从你的问题中很难判断你是否想每次都开始一项新工作,或者如果它仍在运行则跳过轮换。

如果你想每次都重新开始,最简单的方法就是在killall your_command; your_command你的 cron.

否则,请尝试pgrep you_command || your_command在您的 cron 行中仅在未发现当前正在运行的情况下执行。

您还可以更花哨,在某种运行文件中注册作业的 PID,然后在开始工作之前检查该运行文件中是否有活动作业。如果你找到一个,你可以退出并让它运行,或者杀死另一个,并将你自己的 PID 标记为当前正在运行的 PID。

相关内容