繁体   English   中英

在PHP中使用Flock进行文件访问同步

[英]File access synchronization with flock in php

我试图了解使用PHP中的flock同步文件读/写的正确方法。

我有两个PHP脚本。

testread.php:

<?
$fp=fopen("test.txt","r");
if (!flock($fp,LOCK_SH))
  echo "failed to lock\n";
else
  echo "lock ok\n";
while(true) sleep(1000);

?>

和testwrite.php:

<?
$fp=fopen("test.txt","w");
if (flock($fp,LOCK_EX|LOCK_NB))
{
  echo "acquired write lock\n";
}
else
{
  echo "failed to acquire write lock\n";
}
fclose($fp);
?>

现在,我运行testread.php并将其挂在那里。 然后在另一个会话中运行testwrite.php。 不出所料,flock在testwrite.php中失败。 但是,退出testwrite.php时,将清除文件test.txt的内容。 事实是,即使文件已在另一个进程中锁定,fopen也会始终成功。 如果以“ w”模式打开文件,则无论锁定如何,文件内容都会被删除。 那么这里的羊群有什么意义呢? 它并没有真正保护任何东西。

您正在testwrite.phpw模式下使用fopen() 使用w选项时, fopen()将在打开文件后截断该文件。 (请参阅fopen() )。

因此,在尝试获取排他锁之前,示例中的文件将被截断。 但是,您需要一个打开的文件描述符才能使用flock()

解决此难题的方法是使用与您正在使用的文件不同的锁定文件。 flock()手册页提到了这一点:

因为flock()需要文件指针,所以您可能必须使用特殊的锁定文件来保护要截断的文件的访问,方法是在写模式下打开文件(对fopen()使用“ w”或“ w +”参数) )。

公认的答案过于复杂。 您可以简单地使用“ c”参数打开文件,该参数不会截断文件。 然后仅在获得锁后才调用ftruncate()。

文档中

'c'打开文件仅用于写入。 如果该文件不存在,则会创建它。 如果存在,则它既不会被截断(与“ w”相对),也不会对该函数的调用失败(与“ x”的情况相同)。 文件指针位于文件的开头。 如果希望在尝试修改文件之前先获得咨询性锁(请参阅flock()),这可能会很有用,因为使用'w'可以在获取锁之前截断文件(如果需要截断,则可以将ftruncate()在请求锁定后使用)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM