编辑:
我已经改变了标题“为什么第二个客户端在第一个呼叫完成之前无法访问该页面?” “为什么来自同一IP的第二个客户端在显示页面之前有20秒超时?”.因此在所有编辑之前推理并不相同.
这里有2个网址:
/ home和/ sleep.
/ home显示主页
/睡眠睡10秒
我有2个客户:
客户端1:/ sleep – >等了10秒
客户端1:/ sleep,Client 2:/ home – >客户端1等待10秒,客户端2立即加载页面.
客户端1:/ sleep,Client 2:/ sleep – >客户端1等待10秒,客户端2等待20秒
为什么?我该怎么躲闪呢?
如果此页面已被其他人调用,我想展示一些特别的东西.
这是我的代码:
$fileHandler = fopen('process.lock', 'w');
$hasLock = flock($fileHandler, LOCK_EX | LOCK_NB);
if (!$hasLock) {
return('already running'); // it never goes here.
}
for ($i = 0; $i < 10; ++$i) {
echo nl2br("$i" . PHP_EOL);
ob_flush();
flush();
sleep(1);
}
flock($fileHandler, LOCK_UN);
fclose($fileHandler);
编辑
多么巧合.实际上,它在20秒的等待时间内返回“已经运行”.这意味着如果我在for中有一个无限循环,我将在客户端2上“已经运行”,但是超时为20秒.
我只是想知道它是什么超时.
EDIT2
我做了进一步的测试,证明它来自Apache或PHP配置,而不是我使用的功能:
客户端1上/睡眠:
public function sleep() {
// this is the endpoint of http://127.0.0.1/sleep
sleep(300);
}
然后我编辑这个文件,以便Client 2对该函数进行调用:
public function sleep() {
// this is the endpoint of http://127.0.0.1/sleep
die('hello');
}
如果我从5秒间隔(对文件进行更改的时间)运行我的两个客户端,则第二个客户端仍然等待20秒,然后再打印hello.
EDIT3
客户端1:127.0.0.1/sleep – >等了10秒
客户端2:192.168.0.10/sleep – >等待10秒没有延迟
我的结论是问题来自同一IP的请求.为什么?
最佳答案 根据
PHP documentation,flock()于
windows performs Mandatory locking.
这意味着系统会在文件操作(包括fopen)上为您检查锁定.
在Linux上,它将执行建议锁定,这需要访问该文件的进程在所有尝试通过调用flock()获取锁定时进行协作.
Windows变体允许您锁定一次并阻止所有其他程序,包括那些不了解您的代码的程序.
您的第二个客户端阻止fopen()调用等待锁定释放.
编辑:我确实意识到我实际上没有回答你的第一个问题:如何避免这种情况.一个简单的解决方法是将代码移动到Linux服务器,如果有可能的话.否则我建议你搜索如何在Windows上进行咨询锁定.