为什么来自同一IP的第二个客户端在显示页面之前有20秒超时?

时间:2016-02-22 13:55:51

标签: php apache

编辑:

我已经更改了标题“为什么第二个客户端无法访问该页面,直到第一个呼叫完成?”到“为什么来自同一IP的第二个客户端有一个显示页面前20秒超时?“。 所以在所有修改之前推理都不一样。

这里有2个网址: /home/sleep

/home显示主页

/sleep睡10秒

我有2个客户:

客户1 /sleep - >等待10秒

客户端1 /sleep客户端2 /home - > 客户端1 等待10秒,客户端2 即时加载页面。

客户端1 /sleep客户端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配置,而不是我使用的功能:

/sleep上的

客户端1

public function sleep() {
    // this is the endpoint of http://127.0.0.1/sleep
    sleep(300);
}

然后我编辑此文件,以便客户端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 - &gt;等待10秒

客户端2 192.168.0.10/sleep - &gt;等待10秒没有延迟

我的结论是问题来自同一IP的请求。为什么?

1 个答案:

答案 0 :(得分:2)

根据PHP documentationwindows performs Mandatory locking flock()。 这意味着系统会在文件操作(包括fopen)上检查锁定。

在Linux上,它会执行建议性锁定,要求所有试图通过调用flock()来获取锁定的访问该文件的进程合作。

Windows变体允许您锁定一次并阻止所有其他程序,包括那些不了解您的代码的程序。

您的第二个客户端在fopen()电话上阻止等待锁定释放。

编辑:我确实意识到我实际上没有回答你的第一个问题:如何避免这种情况。一个简单的解决方法是将代码移动到Linux服务器,如果有可能的话。否则,我建议你搜索如何在Windows上进行咨询锁定。

相关问题: PHP flock() behaviour difference on Windows vs Linux