【问题标题】:Stopping Parallel Execution of PHP Script停止 PHP 脚本的并行执行
【发布时间】:2010-06-26 15:59:16
【问题描述】:

我试图阻止我的 cron 脚本允许它并行运行。我需要它,以便如果当前没有执行它,脚本将被允许运行,直到它完成、脚本超时或发生异常。

我一直在尝试使用 PHP 的flock 函数来锁定文件,运行脚本然后释放锁。但是,看起来我仍然可以并行运行该脚本多次。我错过了什么吗?

顺便说一句,我正在使用 Mac 文件系统在 Mac OS X 上进行开发,也许这就是文件锁被忽略的原因?虽然 PHP 文档只关注 NTFS 文件系统?

        // Construct cron lock file path
    $cronLockFilePath = realpath(APPLICATION_PATH . '/locks/cron');

    // Get cron lock file
    $cronLockFile = fopen($cronLockFilePath, 'r');

    // Lock cron lock file
    if (flock($cronLockFile, LOCK_EX)) {

echo 'lock';
sleep(10);

    } else {

echo 'no lock';
    }

【问题讨论】:

    标签: php


    【解决方案1】:

    您的想法基本上是正确的,但是修改文件锁通常会导致奇怪的行为。

    只需在脚本开始时创建一个文件并在最后删除它。该文件的存在将指示 cron 是否已在运行。确保文件最终被删除,即使 cron 在中途遇到错误。

    【讨论】:

    • 处理错误应该不是问题,我只会捕获所有异常,然后取消链接创建的文件......但我想处理脚本终止是不可能的,例如服务器重启,apache重新启动,或脚本超时......因为它是一个 cron 文件,我可能只是让脚本运行而没有超时。
    • 您可以尝试使用两个脚本:第一个创建“锁定”文件,执行您当前的 cron 脚本,然后删除“锁定”文件。所以即使你当前的 cron 脚本爆炸了,第一个脚本仍然会解除锁定。我已经做过的另一件事:如果您的脚本检测到“锁定”文件在那里,但 filectime 超过一个小时,您仍然继续删除它,因为很可能出现问题。
    【解决方案2】:

    来自文档:

    警告

    在某些操作系统上,flock() 是 在流程层面实施。什么时候 使用多线程服务器 API,例如 您可能无法依赖的 ISAPI flock() 保护文件免受其他 并行运行的 PHP 脚本 同一服务器实例的线程!

    您可以尝试创建和删除文件,或者在其中写入一些内容。

    【讨论】:

    • 我看到了,我看到了,我看到了一些其他方法,它们依赖于创建文件,然后在完成后删除。但是,这将无法处理脚本超时和脚本在执行 unlink 函数之前终止的异常。因此,尽管脚本可能已终止,但由于尚未删除创建的文件,该脚本将无法再次运行。有没有办法处理这种情况?
    • 首先想到的是,也许您可​​以尝试打开套接字,而当其他线程尝试在同一端口上打开相同的套接字时,它们会失败。
    【解决方案3】:

    我认为您可以做的是在脚本开始执行时在某处(lock.txt 或其他东西)编写一个常规文件,没有任何羊群,并在脚本停止运行时将其删除。然后总是在初始化时检查该文件是否已经存在——另一个实例正在运行。

    【讨论】:

    • 检查文件存在性和锁定文件创建至少是两个命令,这意味着仍然可能存在竞争条件。 flock 无缘无故不存在。
    猜你喜欢
    • 1970-01-01
    • 2011-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-28
    • 1970-01-01
    相关资源
    最近更新 更多