php中flock的文件访问同步
我试图理解在PHP中使用flock同步文件读/写的正确方法 我有两个php脚本 testread.php:php中flock的文件访问同步,php,file,flock,Php,File,Flock,我试图理解在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
<?
$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中失败。但是,文件test.txt的内容在testwrite.php退出时被清除。事实是,即使文件已在另一个进程中锁定,fopen也始终会成功。如果文件是以“w”模式打开的,则无论锁定如何,文件内容都将被擦除。那么,羊群在这里的意义是什么呢?它并不能真正保护任何东西 您正在testwrite.php
中使用fopen()
和w
模式。使用w
选项时,打开文件后fopen()
将截断文件。(见附件)
因此,在您的示例中,在尝试获取独占锁之前,文件会被截断。但是,为了使用flock()
,您需要一个打开的文件描述符
解决这个难题的方法是使用一个与您正在处理的文件不同的锁定文件。手册页提到了这一点:
因为flock()需要一个文件指针,所以您可能必须使用一个特殊的锁文件,通过在写模式下打开要截断的文件来保护对该文件的访问(fopen()使用“w”或“w+”参数)
公认的答案过于复杂。您只需使用“c”参数打开文件,它不会截断文件。然后,仅当您获得锁时才调用ftruncate() 从: “c”打开该文件仅用于写入。如果该文件不存在,则为 创建。如果它存在,则它既不会被截断(与“w”相反), 对该函数的调用也不会失败(如“x”的情况)。这个 文件指针位于文件的开头。这可能是 如果希望在之前获得建议锁(请参见flock()),则此选项非常有用 试图修改该文件,因为使用“w”可能会截断该文件 在获得锁之前(如果需要截断,则为ftruncate() 可在请求锁后使用)
你不可能把羊群放在福彭之前。如果不首先使用fopen获取有效的文件指针,$fp甚至不是有效值。你怎么能在空值上使用flock?@StephenCheng当然!!我怎么能忽视这一点?!。。我需要休息一会儿,但明天会有所帮助……这是我从一开始就怀疑的。我确实错过了文档页面上的注释行。感谢您指出。flock需要一个文件句柄,必须由fopen返回。