【问题标题】:PHP max_execution_time not timing outPHP max_execution_time 没有超时
【发布时间】:2012-06-30 19:45:12
【问题描述】:

如果睡眠被计算为超时或类似的东西,这不是常规问题之一。好的,问题来了:我已将 PHP 的 max_execution_time 设置为 15 秒,理想情况下,当它超过设置的限制时应该超时,但事实并非如此。更改 php.ini 文件后,Apache 已重新启动,并且 ini_get('max_execution_time') 一切正常。有时脚本运行长达 200 秒,这太疯狂了。我没有任何数据库通信。该脚本所做的只是在 unix 文件系统上查找文件,并且在某些情况下重定向到另一个 JSP 页面。脚本上没有 sleep()。

我这样计算 PHP 脚本的总执行时间:

在我设置的脚本开头:

$_mtime = microtime();  
$_mtime = explode(" ",$_mtime);
$_mtime = $_mtime[1] + $_mtime[0]; 
$_gStartTime = $_mtime;

结束时间($_gEndTime)的计算方法类似。
总时间是在我注册的关机函数中计算的:

register_shutdown_function('shutdown');
.............
function shutdown()
{
   ..............
   ..............
   $_total_time = $_gEndTime - $_gStartTime;
   ..............
   switch (connection_status ())
    {
    case CONNECTION_NORMAL:
      ....
      break;
      ....
    case CONNECTION_TIMEOUT:
      ....
      break;
      ......
    }
} 

注意:我不能使用 $_SERVER['REQUEST_TIME'] 因为我的 PHP 版本不兼容。这很糟糕 - 我知道。

1) 好吧,我的第一个问题显然是为什么我的 PHP 脚本即使在设置的超时限制之后仍然执行?
2) Apache 有 300 秒的 Timeout 指令,但 PHP 二进制文件不读取 Apache 配置,这应该不是问题。
3) 是否有可能让 PHP 进入睡眠模式?
4)我是否以错误的方式计算执行时间?有没有更好的方法来做到这一点?


此时我被难住了。 PHP 向导 - 请帮助。

编辑: 我刚刚发现流操作不是一些日志的原因。即使没有执行流式操作,延迟在脚本中也是随机的。上下文切换可能就是原因。但我仍然没有明确的答案。我查了Real max_execution_time for PHP on linux,但我不确定我想试试。还有其他建议吗?

【问题讨论】:

  • 我相信文件系统操作也不计入时限计算中。
  • 您知道,您可以使用microtime(true) 立即获取float...
  • @lonesomeday:你确定吗?
  • @JoeyEzekiel 是的。查看set_time_limit 的文档。明确包含“流操作”
  • @deceze 是的,我知道。但这是遗留代码,我现在并没有真正尝试查看代码的质量。还是谢谢。

标签: php apache


【解决方案1】:

max_execution_time 仅限制 脚本 执行时间本身 - cpu 时间 您的脚本。如果操作系统上下文切换到另一个进程并在那里花费了一些时间,它也不会被计算在内。因此,测量真实世界的时间并期望在 30 秒后超时,在任何给定时间都不会成立。当然,它也忽略任何systemexec 或网络时间

【讨论】:

  • 确实......即使等待数据库查询或处理数据流也不在等式
  • 我没有任何系统,执行调用,但我也没有调用任何外部代码。文件系统操作是否计入 max_execution_time 限制?比如说,一个 fopen()
  • @JoeyEzekiel 即使 you 不执行任何未考虑到max_execution_time 的操作,操作系统上下文切换仍在发挥作用,您几乎无能为力。好吧,你可以renice运行php的进程(本例中为apache),但我不推荐它。
  • @JoeyEzekiel 是的,请阅读 PHP 手册页上的注释:php.net/manual/en/function.set-time-limit.php 流操作也会影响时间限制(而 fopen/fread/etc 是流操作)
  • @JoeyEzekiel 您不能在max_execution_time 中包含这些操作。为了克服这个(有点)你可以使用register_tick_function注册一个回调来检查已经过去了多少时间,但这是非常低效的(因为回调会被调用很多并且会浪费很多cpu周期)而且我强烈建议不要这样做
【解决方案2】:

如果您需要在一定时间后超时(根据 cmets)为什么不调用

 $startscript = microtime();

 //do some stuff

if (microtime() - $startscript > 1500)
{
  dotimeout();
}


  // do more stuff

if (microtime() - $startscript > 1500)
{
  dotimeout();
}

  // do more stuff

if (microtime() - $startscript > 1500)
{
  dotimeout();
}

你明白了。不是很漂亮,但可能有用。

【讨论】:

  • 当我知道延迟肯定会发生时,这可能会起作用。但就我而言,延迟是随机的。因此,例如:如果第一次检查通过并且 microtime() - $startscript 是任何小于 1500 的值,并且如果延迟发生在第二次检查被调用之前,那么这又是同一个故事。还是谢谢...!
猜你喜欢
  • 2011-08-06
  • 1970-01-01
  • 2015-07-03
  • 1970-01-01
  • 1970-01-01
  • 2021-03-11
  • 1970-01-01
  • 2019-08-10
  • 1970-01-01
相关资源
最近更新 更多