PHP 超时是否会阻止人们在同一网络上加载页面


Do PHP timeouts stop people on the same network loading pages?

如果我有一个PHP页面正在执行一个需要很长时间的任务,并且我尝试同时从同一站点加载另一个页面,则该页面不会加载,直到第一页超时。例如,如果我的超时设置为 60 秒,那么我将无法加载任何其他页面,直到需要很长时间加载/超时的页面后 60 秒。据我所知,这是预期的行为。

我试图弄清楚的是,创建上述情况的错误/长时间加载PHP脚本是否也会影响同一网络上的其他人。我个人认为这是一个浏览器问题(即,如果我在 chrome 中加载 http://somesite.com/myscript.php 并且它开始在后台工作,那么我无法加载 http://somesite.com/myscript2.php 直到超时,但我可以在 Firefox 中加载该页面)。但是,我听到了相互矛盾的说法,说超时将发生在同一网络上的每个人(IP地址?

我的脚本处理从 sage 导入的一些数据,并且需要相当长的时间才能运行 - 有时它可能会在完成之前超时(即,如果 sage 导入在一周内崩溃),所以我再次运行它,它会从中断的地方继续。我担心办公室的其他工作人员在运行期间无法访问该网站。

您在这里遇到的问题实际上与(我猜)您正在使用会话的事实有关。这可能有点牵强,但它可以解释您所描述的内容。

这实际上不是"预期行为",除非您的 Web 服务器设置为使用单个线程运行单个进程,我对此表示高度怀疑。这将造成Web服务器在任何时候只能处理一个请求的情况,这将影响网络上的每个人。这正是您的Web服务器可能不会像这样设置的原因 - 实际上,我怀疑您会发现不可能像这样配置服务器,因为这会使服务器有些无用。在一些聪明的亚历克插话"Node.js呢?"之前 - 这是一个特例,我相信你已经很清楚了。

当 PHP 脚本打开会话时,它会对存储会话数据的文件具有独占锁。这意味着任何后续请求都将在调用session_start()时阻塞,而 PHP 会尝试获取会话数据文件上的独占锁 - 它不能,因为您之前的请求仍然有一个。上一个请求完成后,它会释放对文件的锁定,下一个请求就可以完成。由于会话是每台计算机的(顾名思义,实际上是每个浏览会话,这就是为什么它在不同的浏览器中工作),这不会影响您网络的其他用户,但是将您的网站设置为即使只是针对您的问题也是一个问题是一种不好的做法,很容易避免。

此问题的解决方案是在完成给定脚本中的会话数据后立即调用session_write_close()。这会导致脚本关闭会话文件并释放其锁定。您应该尝试在开始长时间运行的进程之前完成会话数据,或者在它完成之前不要调用session_start()

从理论上讲,你可以调用session_write_close()然后稍后在脚本中再次调用session_start(),但我发现PHP有时会在这方面表现出错误的行为(我认为这与cookie有关,但不要引用我的话)。显然,请注意设置 cookie 会修改标头,因此您必须在输出任何数据或启用输出缓冲之前调用session_start()

例如,请考虑以下脚本:

<?php
  session_start();
  if (!isset($_SESSION['someval'])) {
    $_SESSION['someval'] = 1;
  } else {
    $_SESSION['someval']++;
  }
  echo "someval is {$_SESSION['someval']}";
  sleep(10);

使用上述脚本,您必须等待 10 秒才能发出第二个请求。但是,如果在echo行之后添加对session_write_close()的调用,则可以在上一个请求完成之前发出另一个请求。

嗯...我没有检查,但我认为对网络服务器的每个请求都在自己的线程中处理。因此,不应阻止不同的请求。试试吧:-)使用不同的浏览器并在大脚本运行时访问您的页面!

犯 错。。我只是看到这对你有用:-)其他人也应该这样做。