如何在PHP中使用flock


How to use flock in PHP?

在我的php代码中,我想创建一个阅读器/写入器代码。因此php代码将会读取或写入一个文件。只能有一个写入器,也可以有多个读取器,但可以同时写入和读取。

如何在PHP中做到这一点?我相信你需要使用flock代码?

我同意Danack的评论- flock()的php文档包含一个非常好的例子:

$fp = fopen("/tmp/lock.txt", "r+");
if (flock($fp, LOCK_EX)) { // exclusive lock will blocking wait until obtained
    fwrite($fp, "Write something here'n");
    // or ...
    execute_code_that_shouldnt_run_twice_at_the_same_time();
    flock($fp, LOCK_UN); // unlock
} else {
    echo "failed to obtain lock";
}
fclose($fp);

请注意,flock()在默认模式下会阻塞等待,直到它可以获得锁。如果另一个进程当前获得了锁,这是正常的情况。


但是不要对flock()函数期望太高。它正在使用所谓的咨询锁,其他进程可以忽略它。例如,在Linux上,PHP的flock()使用内核函数flock(), man 2 flock解释了它是如何工作的:

flock()只放置建议锁;给予适当的权限文件中,进程可以自由地忽略flock()的使用,并执行I/O该文件。

意味着flock()只会给其他进程一个建议。如果他们不关心,他们可以读甚至写,而不管锁(或锁的类型)。然而,手册页是关于Linux的,其他系统可能以不同的方式处理这个问题。(事实并非如此)

但是,由于您是进程的编码器,因此您可以/并且应该在每次访问文件时使用flock()来关心锁。但是您不能确定另一个进程(如文本编辑器)不会覆盖您的文件

如果你想同时读和写,那是不可能的。这是不安全的行为。只要使用独占锁进行写操作,那么您的读取器(使用共享锁)将在等待读取时阻塞。这样他们就永远不能从一个部分完成的文件中读取,但最终总是可以读取的。

哦,不要锁定文件的时间超过需要的时间。如果你正在进行长时间的更改(例如等待网络活动),锁定它,更新,解锁,等到你获得更多的数据,锁定它,更新,解锁。或者更好的是,在内部缓冲数据并一次写入。