[英]PHP locking not working. Can't figure out why
嗨,大家好,我正在跟踪我的问题Acquire_lock()无法正常工作。 Bot仍在快速发送请求。 我无法获得PHP + AJAX的答案。
我已经简化了一切,并拥有三个文件
全部在同一目录中,两个php文件的内容都相同:
<?php
$x = fopen("/var/www/abc.txt", "w");
if (flock($x, LOCK_EX|LOCK_NB)) {
print "No problems, I got the lock, now I'm going to sit on it.";
while (true)
sleep(5);
} else {
print "Didn't quite get the lock. Quitting now. Good night.";
}
fclose($x);
?>
但是,当我加载它们中的任何一个时,我都会收到第二条打印消息:“还没有完全锁定。现在退出。晚安。”
任何人都对这个问题或前者有什么想法吗? 从字面上看,我的智慧到此为止。
一如既往的谢谢。
如果您希望PHP脚本不退出,那么您将需要阻止锁。
羊群文档说您可以通过指定第三个参数来实现。 另外删除LOCK_NB可能会有所帮助。
<?php
$x = fopen("/var/www/abc.txt", "w");
if (flock($x, LOCK_EX, 1)) {
print "No problems, I got the lock, now I'm going to sit on it.";
// wait for 5 seconds
sleep(5);
// Release the lock now so that next script is executed
flock($x , LOCK_UN);
} else {
print "Didn't quite get the lock. Quitting now. Good night.";
}
fclose($x);
?>
这是脚本中发生的事情:
1)您的代码进入while(true)
无限循环while(true)
并且永远不会到达最后的fclose()语句。
2)我在本地服务器上测试了这两个文件:File1.php保持循环,而第二个file2.php给出的文件被锁定则立即发出消息(这意味着第一个文件已正确锁定)。 之后,我尝试刷新两个文件,但它们均未通过锁定测试。
如果使用PHP> 5.3.2,则必须手动解锁文件:
关闭了文件资源句柄关闭时的自动解锁。 现在解锁始终必须手动完成。 资源
如果您使用的是旧版本的PHP,则脚本将在执行完毕后将文件解锁,因为您将进入无限循环,因此脚本永远不会完成,因此文件也不会被解锁。
同样,即使您停止了脚本在浏览器窗口中的运行,与该脚本相关的进程php-cgi.exe仍在运行,并且必须从任务管理器中手动终止(我已验证自己)
解:
1)要解决此问题并使脚本等待锁定,您需要首先通过删除无限循环来确保脚本实际上正常停止:
这是一个将文件锁定30秒(删除循环)的脚本:
<?php
$x = fopen("/var/www/abc.txt", "w");
if (flock($x, LOCK_EX|LOCK_NB)) {
print "No problems, I got the lock, now I'm going to sit on it.";
sleep(30);
fclose($x); // it is good practice to always close even your PHP <5.3.2
}
else {
print "Didn't quite get the lock. Quitting now. Good night.";
}
?>
2)如果您在Linux机器上,则可以使用LOCK_NB标志来确定文件是否被锁定。 LOCK_NB的用法应如下所示:
while ( ! flock($f, LOCK_NB) )
{
sleep(1);
}
这将强制脚本每秒检查一次锁定,并等待其他脚本完成。
3)完成后使用flock($fp, LOCK_UN)
显式删除锁,而不是fclose(); 总之,这是您的代码应如下所示:
<?php
$x = fopen("/var/www/abc.txt", "w");
while(!flock($x,LOCK_NB)
sleep(1);
if (flock($x, LOCK_EX,true)) {
print "No problems, I got the lock, now I'm going to sit on it.";
sleep(30);
fflush($fp); // flush output before releasing the lock
flock($fp, LOCK_UN); // release the lock
} else {
print "Didn't quite get the lock. Quitting now. Good night.";
}
fclose($x);
?>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.