gpt4 book ai didi

php - 读写上的LOCK_EX应该是原子的吗?

转载 作者:IT王子 更新时间:2023-10-28 23:51:50 26 4
gpt4 key购买 nike

file_put_contents ( "file", "data", LOCK_EX )

用于写入(这意味着 - 获取锁并写入)

file_get_contents ( "file", LOCK_EX )

用于读取(这意味着 - 获取锁然后读取)

它会抛出异常吗?提出错误?阻塞直到获得锁?或者至少 - 应该?有没有可能有一天 php 会表现得像这样?

编辑:我知道可以使用重命名 - 我想知道这个问题的答案......

最佳答案

由于这个答案很长,所以总结如下:不,file_get_contents() 不是原子的,因为它不尊重咨询锁

关于 PHP 中的文件锁:

在 PHP 中,在 *nix 平台上,文件系统锁定只是建议性的。根据 the docs (强调我的):

PHP supports a portable way of locking complete files in an advisory way (which means all accessing programs have to use the same way of locking or it will not work). By default, this function will block until the requested lock is acquired; this may be controlled (on non-Windows platforms) with the LOCK_NB option documented below.

所以,只要访问文件的所有进程都使用这种锁定方法,就可以了。

但是,如果您使用健全的网络服务器编写静态 HTML 文件,则锁定将被忽略。在写入过程中,如果有请求进来,Apache 将提供部分写入的文件。锁不会影响读取锁的其他进程。

唯一真正的异常(exception)是,如果您在文件系统上使用 -o mand 的特殊挂载选项来启用强制锁定(但这并没有真正使用太多,并且可能会降低性能)。

阅读 File Locking了解更多信息。即Unix下的部分:

This means that cooperating processes may use locks to coordinate access to a file among themselves, but programs are also free to ignore locks and access the file in any way they choose to.

因此,总而言之,使用 LOCK_EX 将在文件上创建一个咨询锁。只有当阅读器尊重和/或检查锁时,任何读取文件的尝试都会被阻止。如果他们不这样做,锁将被忽略(因为它可以)。

试试看。在一个过程中:

file_put_contents('test.txt', 'Foo bar');
$f = fopen('test.txt', 'a+');
if (flock($f, LOCK_EX)) {
sleep(10);
fseek($f, 0);
var_dump(fgets($f, 4048));
flock($f, LOCK_UN);
}
fclose($f);

当它在 sleep 时,调用它:

$f = fopen('test.txt', 'a+');
fwrite($f, 'foobar');
fclose($f);

输出将是 foobar...

关于file_get_contents具体:

对于您的其他具体问题,首先,file_get_contents 没有 LOCK_EX 参数.所以你不能把它传进去。

现在,查看 source code ,我们可以看到在第 521 行定义的函数 file_get_contents。没有像传递 file_put_contents('file', 'txt', LOCK_EX); 定义在同一文件的第 589 行。

那么,让我们测试一下吧:

在file1.php中:

file_put_contents('test.txt', 'Foo bar');
$f = fopen('test.txt', 'a+');
if (flock($f, LOCK_EX)) {
sleep(10);
fseek($f, 0);
var_dump(fgets($f, 4048));
flock($f, LOCK_UN);
}
fclose($f);

在file2.php中:

var_dump(file_get_contents('test.txt'));

运行时,file2.php 立即返回。所以不,似乎 file_get_contents 根本不尊重文件锁......

关于php - 读写上的LOCK_EX应该是原子的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4899737/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com