繁体   English   中英

PHP锁定不起作用。 不知道为什么

[英]PHP locking not working. Can't figure out why

嗨,大家好,我正在跟踪我的问题Acquire_lock()无法正常工作。 Bot仍在快速发送请求。 我无法获得PHP + AJAX的答案。

我已经简化了一切,并拥有三个文件

  • abc.txt
  • file1.php
  • file2.php

全部在同一目录中,两个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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM