Linux上PHP的实际max_execution_time是多少?

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秒)无法交付页面,我们不希望继续占用资源。我们知道我们可以通过调整设置,例如 MySQL 的 wait_timeout 来控制 SQL 查询的超时时间,但页面超时时间将取决于执行的查询数量。
有些人尝试提出解决方案看起来并不可行。
问:在 Linux 上是否有一种简单的方法来获取真正的 PHP max_execution_time,还是我们最好在其他地方设置超时时间,例如在 Apache 级别上?
3个回答

5
这是一个比较棘手的建议,但如果您愿意修改和重新编译PHP,它一定会做到您想要的。请查看在https://github.com/php/php-src/blob/master/Zend/zend_execute_API.c(文件为Zend/zend_execute_API.c)中的PHP源代码,函数zend_set_timeout。这是实现时间限制的函数。以下是它在不同平台上的工作方式:
  • 在Windows上,创建一个新线程,在其上启动计时器,当计时器结束时,将一个名为timed_out的全局变量设置为1,PHP执行核心会检查每个指令的该变量,然后退出(非常简化)。

  • 在Cygwin上,使用ITIMER_REAL的itimer来测量真实时间,包括任何睡眠、等待等,然后引发一个信号,以中断任何处理并停止处理。

  • 在其他Unix系统上,使用ITIMER_PROF的itimer,它只测量当前进程花费的CPU时间(但同时包括用户模式和内核模式)。这意味着等待其他进程(如MySQL)不计入其中。

现在,您需要做的是将Linux上的itimer从ITIMER_PROF更改为ITIMER_REAL,这当然需要您手动完成、重新编译、安装等。这两者之间的另一个区别是它们在计时器到期时也使用不同的信号。因此,我的建议是更改#ifdef:
#   ifdef __CYGWIN__

转化为

#   if 1

希望你设置ITIMER_REAL和PHP等待的信号为SIGALRM。

总之,这个想法从未经过测试(我将其用于某些非常特定的系统中,其中ITIMER_PROF已损坏,并且它似乎可以工作),不受支持等等。使用时需自行承担风险。它可能适用于PHP本身,但如果它们以任何原因使用SIGALRM信号或其他计时器,则可能会破坏PHP Apache中的其他模块。


1

这是一个旧问题并已有答案。但出于帮助他人的目的,我想指出 request_terminate_timeout php-fpm 选项。如果您正在使用 PHP-FPM,则很可能需要它。

如果设置了此选项,则可以告诉 PHP-FPM 在 N 秒后终止请求,而不管 PHP 执行了什么。

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


-2

来自 httpd.conf:

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

Timeout 300


1
这不会影响PHP处理。 - kuba
实际上,我已经测试了将Apache的“TimeOut”设置为“2”(秒),但它根本没有任何效果。约翰,除了“mod_reqtimeout”之外,你还能推荐些什么吗? - Max

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接