2010-06-26 205 views
1

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

我一直在尝试使用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'; 
    } 

回答

3

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

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

+0

处理错误不应该是一个问题,我只会捕获所有异常,然后取消链接创建的文件...但我想象,处理脚本终止是不可能的,例如服务器重新启动,apache重新启动或脚本超时。 。因为它是一个cron文件,我可能会让脚本运行而不会超时。 – cappuccino 2010-06-26 08:08:44

+0

您可以尝试使用两个脚本:第一个创建“锁定”文件,执行当前的cron脚本,然后删除“锁定”文件。所以即使你的当前cron脚本爆炸了,第一个脚本仍然会删除锁定。 我已经做过的另一件事是:如果脚本检测到“lock”文件存在,但filectime超过一个小时,则继续前进并将其删除,因为很可能出现问题。 – FlorianH 2010-06-26 09:43:40

0

我觉得你可以做的是写一个普通文件的地方(lock.txt或东西),当脚本开始执行,没有任何的羊群,脚本停止运行时将其删除。然后总是检查初始化文件是否已经存在 - 另一个实例正在运行。

+0

文件存在和锁文件创建检查至少有两个命令,这意味着它仍然有可能存在竞争条件。 'flock'不是没有理由的。 – cweiske 2011-05-02 12:00:50

1

从文档:

警告

在某些操作系统群()是 在进程级实现。当 使用多线程服务器API(如 ISAPI)时,您可能无法依赖 flock()来保护文件免受其他 PHP脚本并行运行 同一服务器实例的线程!

您可以尝试创建和删除文件,或者写入文件。

+0

我明白了,我看到了一些其他方法,它们依赖于创建文件然后删除一次完成。然而,这不会能够处理脚本超时和异常,其中脚本在执行解除链接功能之前被终止。因此,尽管脚本可能已被终止,但由于创建的文件尚未被删除,脚本将无法再次运行。有没有办法处理这种情况? – cappuccino 2010-06-26 08:02:46

+0

首先想到的是,也许你可以尝试打开套接字,而当其他线程试图在同一端口上打开同一个套接字时,它们会失败。 – codez 2010-06-26 08:12:12