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

PHP flock()不锁定

皇甫宇定
2023-03-14

我很难理解为什么flock()在以下场景中不能正常工作。

下面的代码放在两个不同的PHP脚本中,一个是“test1.PHP”,另一个是“test2.PHP”。代码的要点是创建一个其他进程(正确使用flock()代码)都无法写入的文件。将有许多不同的PHP脚本尝试获取此文件的独占锁,但在任何给定时间只有一个脚本应该具有访问权限,其余所有脚本在无法获取锁时都会正常失败。

我测试这个的方法非常简单。“test1.php”和“test2.php”都放在我的服务器上一个可通过web访问的目录中。然后从Firefox之类的浏览器执行第一个脚本,然后紧接着从另一个浏览器选项卡执行第二个脚本。当代码从两个不同的PHP脚本(如“test1.PHP”和“test2.PHP”)运行时,这可能会起作用,但当代码从同一个“test1.PHP”脚本或“test2.PHP”脚本运行两次时,运行的第二个脚本不会立即返回失败。

我能想到的唯一原因是flock()将具有相同文件名的所有PHP进程视为同一进程。如果是这种情况,那么当“test1.php”或“test2.php”运行两次(从两个不同的浏览器选项卡)时,php将它们视为同一个进程,因此不会使锁定失败。但对我来说,PHP这样设计是没有意义的,因此我听说如果有人能帮我解决这个问题。

提前谢谢!

<?
$file = 'command.bat';

echo "Starting script...";
flush();

$handle = fopen($file, 'w+');
echo "Lets try locking...";
flush();

if(is_resource($handle)){
    echo "good resource...";
    flush();

    if(flock($handle, LOCK_EX | LOCK_NB) === TRUE){
        echo "Got lock!";
        flush();
        sleep(100);
        flock($fp, LOCK_UN);
    }else{
        echo "Failed to get lock!";
        flush();
    }
}else{
    echo "bad resource...";
    flush();
}

exit;

非常感谢您在以上方面的帮助!

谢谢你,丹尼尔

共有2个答案

景令秋
2023-03-14

公认的解决方案显然是尝试创建一个链接。

很多关于这个话题的讨论:http://www.php.net/manual/en/function.flock.php

高兴贤
2023-03-14

我也遇到过同样的情况,发现问题出在浏览器上。

当对同一URL发出多个请求时,即使跨选项卡或窗口这样做,浏览器也足够“智能”,可以等待第一个请求完成,然后浏览器尝试运行后续请求。

因此,虽然看起来锁不起作用,但实际情况是浏览器(Chrome和火狐)在运行第二个请求之前正在等待第一个请求完成。

您可以通过在Chrome和Firefox中分别打开一次相同的URL来验证这种情况。通过这样做,就像我所做的那样,你可能会看到锁确实像预期的那样工作。

 类似资料:
  • 问题内容: 帮助客户解决他们遇到的问题。我更多地是sysadmin / DBA的人,所以我在努力帮助他们。他们说这是内核/环境中的错误,在我坚持要在他们的代码中或寻求供应商对OS的支持之前,我试图证明或证明这一点。 发生在Red Hat和Oracle Enterprise Linux 5.7(和5.8)上,应用程序用C ++编写 他们遇到的问题是主线程启动一个单独的线程来执行可能长时间运行的TCP

  • 问题内容: 我在这里思考:如果您有2个线程执行需要同步的FAST操作,那么非阻塞方法不是比阻塞/上下文切换方法更快/更好的方法吗? 非阻塞的意思是: while(true){如果(checkAndGetTheLock())中断;} 如果您有太多线程在锁中循环,我唯一想到的就是饥饿(CPU耗尽)。 如何平衡一种方法与另一种方法? 问题答案: 以下是 Java Concurrency in Pract

  • 我正在编写一个应用程序来管理或自定义Android设备的解锁屏幕。它的工作原理如下: 用户使用电源按钮锁定屏幕。 用户尝试解锁屏幕,从而再次按下电源按钮 我的活动弹出--屏幕仍然锁定 用户回答问题,如果答案正确,屏幕解锁 我已经为第三步创建了一个活动,并将以下代码添加到其方法中: 这工作正常,完全符合我的期望。我的问题是第四步。我已经搜索并找到了许多解决方案,但没有一个适合我。 如何以编程方式锁定

  • 问题内容: 天真的问题.. 我读过之前说过:“ MUTEX只能通过锁定它的线程来解锁。 ” 但是我写了一个程序,其中 THREAD1 锁定了mutexVar并进入睡眠状态。然后 THREAD2 可以直接解锁MutexVar进行一些操作并返回。 ==>我知道每个人都说我为什么这样做?但是我的问题是-这是MUTEX的正确行为吗? ==>添加示例代码 问题答案: 您所做的只是不合法的,行为是不确定的。互

  • 我的问题是。。。为什么选择completionLock。run方法中的lock()未锁定资源。当我在系统中运行程序时。出来println(Thread.currentThread())。getName()) 我得到以下输出:Thread-1 Thread-0 Thread-0 Thread-1 NoLock ATM:130 Locked ATM:160应该是:160程序终止。 还有什么是等到完成才

  • 我看不出有什么区别。我读到了这篇文章:actual-use-of-lockinterruptbly-for-a-reentrantlock 想测试一下。代码如下: 这里是Inturrept班 控制台输出: 正如回答中提到的“这与常规锁()相同。但如果另一个线程中断,等待的线程lockInterruptbly()将抛出InterruptedException。”即使它是锁着的。lock()或lock