我很难弄清楚为什么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;
任何与上述的帮助是非常感谢!
谢谢你丹尼尔
3条答案
按热度按时间ars1skjm1#
我遇到了同样的情况,发现问题出在浏览器上。
当对同一URL进行多个请求时,即使跨选项卡或窗口这样做,浏览器也足够“智能”,可以等到第一个请求完成,然后浏览器尝试运行后续请求。
因此,虽然看起来锁不起作用,但实际情况是浏览器(Chrome和Firefox)在运行第二个请求之前正在等待第一个请求完成。
您可以通过在Chrome和Firefox中分别打开一次相同的URL来验证这一点。通过这样做,正如我所做的那样,您可能会看到锁确实按预期工作。
kfgdxczn2#
flock有很多限制,包括多线程服务器、NFS卷等。
公认的解决方案显然是尝试创建一个链接。
关于这个主题有很多讨论:http://www.php.net/manual/en/function.flock.php
xxe27gdn3#
您的脚本正确。
实际发生的是fopen()在等待文件被打开!
如果你用sleep(20)运行第一个脚本;
和第二个脚本与睡眠(1);
您会注意到,第二个脚本实际上等待了20秒,直到文件被解锁。
因此,它永远不会显示“获取锁失败”,除非发生严重错误。