5

根据文档:

max_execution_time only affect the execution time of the script itself. 
Any time spent on activity that happens outside the execution of the script
such as system calls using system(), stream operations, database queries, etc.
is not included when determining the maximum time that the script has been running.
This is not true on Windows where the measured time is real.

这通过测试得到证实:

不会超时

<?php
set_time_limit(5);
$sql = mysqli_connect('localhost','root','root','mysql');
$query = "SELECT SLEEP(10) FROM mysql.user;";
$sql->query($query) or die($query.'<br />'.$sql->error);
echo "You got the page";

会超时

<?php
set_time_limit(5);
while (true) {
  // do nothing
}
echo "You got the page";

我们的问题是,我们真的希望 PHP 超时,不管它在做什么,在给定的时间后(因为如果我们知道我们没有以可接受的数量交付页面,我们不想让资源保持忙碌)时间,比如 10 秒)。我们知道我们可以为 SQL 查询设置诸如MySQL wait_timeout之类的设置,但页面超时将取决于执行的查询数量。

有些人试图提出解决方法,但似乎无法实施。

问:有没有一种简单的方法可以PHP max_execution_time在 linux 上获得一个真实的,或者我们是否在其他地方更好地计时,例如Apache水平?

4

3 回答 3

5

这是一个相当棘手的建议,但如果您愿意修改和重新编译 PHP,它肯定会满足您的需求。

看看https://github.com/php/php-src/blob/master/Zend/zend_execute_API.c的 PHP 源代码(文件是Zend/zend_execute_API.c),在 function zend_set_timeout。这是实现时间限制的功能。以下是它在不同平台上的工作方式:

  • 在 Windows 上,创建一个新线程,在其上启动一个计时器,当它完成时,设置一个名为timed_out1 的全局变量,PHP 执行核心检查每个指令的这个变量,然后退出(非常简化)

  • 在 Cygwin 上,将 itimer 与 ITIMER_REAL 一起使用,它测量实时,包括任何睡眠、等待等,然后发出一个信号,该信号将中断任何处理并停止处理

  • 在其他 unix 系统上,将 itimer 与 ITIMER_PROF 一起使用,它仅测量当前进程花费的 CPU 时间(但在用户模式和内核模式下)。这意味着等待其他进程(如 MySQL)不计入其中。

现在您要做的是将Linux上的定时器从ITIMER_PROF更改为ITIMER_REAL,这当然需要手动进行,重新编译,安装等。这两者之间的另一个区别是它们在定时器运行时也使用不同的信号出去。所以我的建议是改变ifdef:

#   ifdef __CYGWIN__

进入

#   if 1

这样您就可以将 ITIMER_REAL 和 PHP 等待的信号都设置为 SIGALRM。

无论如何,这整个想法是未经测试的(我将它用于一些非常特定的系统,其中 ITIMER_PROF 被破坏,并且它似乎工作),不受支持等。使用它需要您自担风险。它可能与 PHP 本身一起工作,但它可能会破坏 PHPApache 中的其他模块,如果它们出于某种原因使用 SIGALRM 信号或其他计时器。

于 2012-04-05T10:59:30.493 回答
1

这是一个古老且已回答的问题。但是为了帮助别人,我想指出request_terminate_timeoutphp-fpm 选项。如果您使用的是 PHP-FPM,那么它很可能是您所需要的。

如果设置,此选项允许您告诉 PHP-FPM 在 N 秒后终止请求,无论 PHP 做什么。

有关详细信息,请参阅http://php.net/manual/en/install.fpm.configuration.php#request-terminate-timeout

于 2015-04-17T10:44:22.857 回答
-2

来自 httpd.conf:

Timeout:接收和发送超时前的秒数

超时 300

于 2012-04-05T10:08:29.373 回答