同时写入同一文件

时间:2012-04-24 06:42:05

标签: php filesystems fopen flock

好的,我知道在这个网站上有关于这个问题的类似问题,但这些问题和提供的答案都不是我所需要的。

我正在构建基于平面文件的CMS。 如果,例如:

,该怎么办?
  1. 2,3,10 ....附加模式请求中的fwrite同时来到同一个php文件“contact_form_messages_container.php”?

  2. 2,3,10 ....在“w”模式下fwrite请求来到同一个php文件,它同时保存特定页面访问的简单nubmer?

  3. 我知道flock()函数,但它可能会发生两个或多个flock()请求同时发生...有谁知道这个问题的解决方案?我唯一想到的就是usleep() - 在使用looop一段时间后使用脚本,直到目标文件变为可用,但我不知道它是否有效,在哪里以及如何执行此操作? 有没有人对这个问题有实际的见解? 提前谢谢!

2 个答案:

答案 0 :(得分:0)

在文件被锁定时,将写入操作分叉并将其置于具有休眠状态的while循环中。只要您的应用程序不依赖于按时间顺序进行文件系统调用,它就应该可以工作。

如果您的应用程序依赖于按顺序执行的写入操作,则会对竞争条件开放。

答案 1 :(得分:0)

flock()函数旨在处理文件操作的多个并发读取器和写入器;默认情况下,flock()可以暂停进程,直到可以获得兼容锁(即共享或独占)。一旦获得,稍后可以释放锁以允许其他进程对文件进行操作;当文件关闭或进程结束时,会隐式释放锁。

除非您的文件在NFS上,否则我非常怀疑您是否会遇到同时发出两个冲突锁的情况。


以下说明了使用flock()的基本示例:

// open the file (take care to not use "w" mode)
$f = fopen('file.txt', 'r+');
// obtain an exlusive lock (may suspend the process)
if (flock($f, LOCK_EX)) {
    // this process now holds the only exclusive lock

    // make changes to the file

    // release the lock
    flock($f, LOCK_UN);
}
// don't perform any write operation on $f here
fclose($f);

LOCK_NB标记与LOCK_EXLOCK_SH一起使用可防止该过程被暂停;如果调用返回false,则可以传递第三个参数以确定该进程是否已被挂起(Windows不支持)。

if (false === flock($f, LOCK_EX | LOCK_NB, $wouldblock)) {
    if ($wouldblock) {
        // the lock could not be obtained without suspending the process
    } else {
        // the lock could not be obtained due to an error
    }
}