You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何避免cron定时运行的PHP脚本因未执行完而重复启动?

防止Cron重复运行PHP脚本的几种实用方法

方法一:使用文件锁(最可靠)

利用PHP的flock()函数创建排他锁,脚本启动时尝试获取锁,获取失败则直接退出,避免重复执行。这种方法能自动处理脚本意外崩溃的情况(锁会随进程结束自动释放)。

在script.php开头添加以下代码:

// 定义锁文件路径,建议放在tmp目录或者脚本所在目录
$lockFile = '/tmp/script_run.lock';

// 打开锁文件,模式为读写+创建
$lockHandle = fopen($lockFile, 'w');
if (!$lockHandle) {
    exit("无法创建锁文件\n");
}

// 尝试获取排他锁,LOCK_NB表示非阻塞获取,避免等待
if (!flock($lockHandle, LOCK_EX | LOCK_NB)) {
    exit("脚本已在运行中\n");
}

// 脚本核心逻辑写在这里...

// 脚本结束时可手动释放锁(可选,进程结束后系统会自动释放)
flock($lockHandle, LOCK_UN);
fclose($lockHandle);

方法二:检查系统进程

通过系统命令检查是否已有script.php的进程在运行,判断后决定是否继续执行。注意要过滤掉当前执行的检查命令本身,避免误判。

示例代码:

// 构造检查命令,用[ s ]cript.php的正则技巧过滤grep自身进程
$command = "ps aux | grep '[s]cript.php' | wc -l";
$runningCount = (int)shell_exec($command);

// 如果运行中的进程数大于1,说明已有实例在运行
if ($runningCount > 1) {
    exit("脚本已在运行中\n");
}

// 脚本核心逻辑...

方法三:改用Systemd Timers(Linux系统)

如果你的服务器使用systemd,可以抛弃cron,改用systemd定时器管控脚本执行,天生支持"前一个实例结束才启动下一个"的逻辑。

  1. 创建服务文件script.service:
[Unit]
Description=Run script.php periodically

[Service]
Type=oneshot
ExecStart=/usr/bin/php /path/to/script.php
RemainAfterExit=no
  1. 创建定时器文件script.timer:
[Unit]
Description=Timer for script.php

[Timer]
# 每5分钟执行一次,以上一次执行结束时间为起点计算
OnUnitActiveSec=5min
# 开机后立即执行一次(可选)
OnBootSec=0min

[Install]
WantedBy=timers.target
  1. 启用并启动定时器:
sudo systemctl daemon-reload
sudo systemctl enable --now script.timer

这种方式无需修改脚本本身,由systemd负责实例唯一性管控。


内容的提问来源于stack exchange,提问作者Geckon01

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 07:35:02