【问题标题】:Check if a file is already locked using flock()? [duplicate]使用flock()检查文件是否已经被锁定? [复制]
【发布时间】:2012-04-09 10:11:50
【问题描述】:

我有一个要写入的文件,但我需要先锁定它(使用flock()),以防止任何其他脚本写入它。 所以我有:

$file=fopen($file_p);

if (flock($file, LOCK_EX)) {//lock was successful
    fwrite($file,$write_contents);          
}

但我需要检查它是否已经被锁定,以防止其他脚本写入它。

我该怎么做?

【问题讨论】:

    标签: php flock


    【解决方案1】:

    您的羊群呼叫是检查它是否已被锁定。如果它被锁定,则 if() 语句将失败,因此您可以在其上抛出 else 类似的内容:

    if (flock($file, LOCK_EX)) {//lock was successful
        fwrite($file,$write_contents);
    } else {
        echo "$file is locked.";
    }
    

    【讨论】:

    • AHHH,所以如果文件已经被锁定则返回false?
    • 这是不正确的;请参阅我对 Mike Purcell 几乎相同答案的评论。
    【解决方案2】:

    我会检查我是否无法获得对文件的锁定,如下所示:

    if (!flock($file, LOCK_EX)) {
        throw new Exception(sprintf('Unable to obtain lock on file: %s', $file));
    }
    
    fwrite($file, $write_contents);
    

    【讨论】:

    • 这是不正确的。如果你没有在传递给flock的操作上指定LOCK_NB位掩码,那么默认情况下,这个函数将阻塞直到获得请求的锁 (source)。使用您给出的示例代码,flock不会返回 false 以指示已由另一个进程在文件上取消了锁定,但只会等待该进程释放其锁定。
    • @MarkAmery:不正确怎么办?逻辑很简单,如果无法在文件上获得exclusive lock,则抛出异常。由调用代码决定如何处理异常。
    • 否 - 如果无法获取锁的原因是另一个进程持有它,则您上面的评论与您的​​代码行为方式不匹配。相反,您的代码的行为是“如果您无法获得文件的排他锁,请继续等待,直到可以获得,然后继续。” - 这是flock 的默认行为。您需要使用 LOCK_NB 修饰符,如 Ryan Y 的回答中所示,以使您的代码按照您的评论描述的方式运行。
    • 这就是我要说的,我可以等到获得文件的独占锁定。例如,如果你实现一个基于队列的处理算法,其中可以同时运行 12-14 个并行进程,每个进程都需要写入同一个文件(即日志文件),那么我想确保每个进程都获得排他锁,如果不能,则等到它可以。我从来没有遇到过等待时间成为问题的情况。
    • 当然,但这不是 OP 提出的问题的答案,即如果文件已被锁定,如何检查。正如我最初理解您的回答和您之前的评论一样,您是说如果另一个进程持有锁,您的代码将执行该检查并引发异常。听起来您并不是有意暗示这一点,而是提供上面的 sn-p 作为“如何检查文件是否已被锁定?”的答案。没有注意到您提供替代方法是误导。
    【解决方案3】:

    docs 中所述,使用LOCK_NB 进行非阻塞尝试以获取锁,并在失败时检查$wouldblock 参数以查看是否有其他东西持有锁。

    if (!flock($fp, LOCK_EX|LOCK_NB, $wouldblock)) {
        if ($wouldblock) {
            // something already has a lock
        }
        else {
            // couldn't lock for some other reason
        }
    }
    else {
        // lock obtained
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-05-30
      • 1970-01-01
      • 2012-10-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-09
      相关资源
      最近更新 更多