如何锁定文件以防止读取/写入同一文件的多个 ajax 请求?

Posted

技术标签:

【中文标题】如何锁定文件以防止读取/写入同一文件的多个 ajax 请求?【英文标题】:How can I lock a file to protect against multiple ajax requests reading/writing the same file? 【发布时间】:2019-10-01 15:53:32 【问题描述】:

我目前正在尝试阻止读取已存在且包含内容的文件。我正在使用flock 方法来尝试阻止正在运行的脚本的其他实例访问它,但它不起作用。这只是多核服务器的问题。

while ($aEvent = current($aEvents))
    $sLockFile = '/var/tmp/'.md5($aEvent['id']).'.LCK';
    $oFile = fopen($sLockFile, 'c+');
    if (flock($oFile, LOCK_EX) && fgets($oFile) == '') 
        fwrite($oFile, 'locked');
        fclose($oFile);
     else 
        fclose($oFile);
        next($aEvents);
        continue;
    
    /*
     * Do stuff here.
     */
    next($aEvents);

因此,从这段代码中,我希望创建、锁定和写入文件,并且任何尝试随后读取/写入文件的请求要么在 flock 调用或空检查时停止。实际上,如果代码同时受到足够多的 ajax 请求,则同一文件被创建/覆盖多次。有什么方法可以保证 php 线程的安全吗?

【问题讨论】:

【参考方案1】:

听起来您想将LOCK_NB 位添加到您的flock 调用中。来自the flock docs:

默认情况下,该函数会一直阻塞,直到获得请求的锁;这可以通过 LOCK_NB 选项来控制

您的代码将在每次调用flock 时阻塞,直到可以获取锁为止。如果存在锁,听起来您想跳到else 块。如果是这样,你想在你的代码中这样做:

<?php
if (flock($oFile, LOCK_EX | LOCK_NB) && fgets($oFile) == '')
...

【讨论】:

将尝试并报告结果。但是根据我对那个 doc 块的理解,默认情况下它会阻塞直到它锁定。 LOCK_NB 选项会禁用它,不是吗? 是的,正如我所料,这似乎没有什么不同。 是的,你是想阻塞直到获得锁,还是快速失败进入 else 块?我不确定我是否理解您要执行的操作。 只要文件只被访问一次,我可以接受任何一个。

以上是关于如何锁定文件以防止读取/写入同一文件的多个 ajax 请求?的主要内容,如果未能解决你的问题,请参考以下文章

如何锁定文件并避免在写入时读取

如何在写入期间锁定文件以使其在打开时无法读取?

如何锁定 Access 数据库以防止写入

当多个进程尝试同时写入然后从文件中读取时,如何防止竞争条件

.NET 锁定还是 ConcurrentDictionary?

锁定文件以防止多个用户访问它的最佳方法是啥