当前位置: 首页 > 知识库问答 >
问题:

php中flock的文件访问同步

常乐
2023-03-14

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

我有两个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”模式打开,无论锁如何,文件内容都将被擦除。那么这里的羊群有什么意义呢?它并不能真正保护任何东西。

共有2个答案

邬英武
2023-03-14

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

从文件中:

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

邵宏达
2023-03-14

您正在testwrite中使用fopen()w模式。php。使用w选项时,打开文件后fopen()将截断文件。(请参见fopen())。

因此,在您尝试获取独占锁之前,文件会在示例中被截断。但是,为了使用flock(),您需要一个打开的文件描述符。

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

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

 类似资料:
  • 本文向大家介绍PHP文件锁函数flock()详细介绍,包括了PHP文件锁函数flock()详细介绍的使用技巧和注意事项,需要的朋友参考一下 文件操作系统是在网络环境下完成的,可能有多个客户端用户在同一个时刻对服务器上的同一个文件访问。当这种并发访问产生时,很可能会破坏文件中。例如一个用户正在向文件中写入数据,当还没有写完时,其他用户在这一时刻也向这个文件中写数据,就会造成数据写入混乱。还有,当用户

  • 问题内容: 搜寻了几个小时后,就开始对此完全取笑。我还在网站上看到了该问题的各种变体,但似乎无法使其正常工作。JFrame需要从ini文件中读取数据,并且我已经创建了一种打开该文件的方法。所述文件存储在jar文件内称为资源的文件夹中。 当我在编译后运行代码时,这当然可以完美地工作,但是在导出到.jar文件后会引发异常。我已经研究过使用InputStream,FileInputStream,但似乎找

  • 问题内容: 我在Ubuntu上获取对.mdb文件(MS-Access db)的访问权限时遇到问题。我需要完全访问权限(也可以读写)。 最初,项目是使用odbc在Windows上构建的(并且一切正常。)但是当我在linux服务器上移动它时出现了问题。 目前,已安装用于odbc的PHP扩展。但是我找不到用于Access的任何免费的ODBC驱动程序。我尝试使用MDB工具,但似乎仅适用于阅读。 也许有人可

  • 问题内容: 我创建了一个小型Java servlet,其目的很简单:调用它后,它将执行以下步骤: 从本地文件系统读取文件foo.json 处理文件中的数据并对其进行一些更改 将更改写回文件 代码的简化版: 现在,我面临一个问题,即可能有两个或多个对servlet的http请求几乎同时调用servlet。为了避免对同一文件进行多次并行写访问,我需要以某种方式进行同步。根据我对servlet生命周期过