According to the documentation:
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','MysqL');
$query = "SELECT SLEEP(10) FROM MysqL.user;";
$sql->query($query) or die($query.'
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查询,但页面超时将取决于执行的查询数.
有些人试图提出workarounds,但似乎没有实现.
问:有没有一种简单的方法可以在Linux上获得真正的PHP max_execution_time,或者我们是否更好地在其他地方超时,例如Apache级别?
在函数zend_set_timeout查看https://github.com/php/php-src/blob/master/Zend/zend_execute_API.c的PHP源代码(文件是Zend / zend_execute_API.c).这是实现时间限制的功能.以下是它在不同平台上的工作方式:
>在Windows上,创建一个新线程,在其上启动一个计时器,当它完成时,将名为timed_out的全局变量设置为1,PHP执行核心检查每个指令的变量,然后退出(非常简化)
>在Cygwin上,使用itimer和ITIMER_REAL,它可以测量实时,包括任何睡眠,等待等等,然后发出一个信号,中断任何处理并停止处理
>在其他unix系统上,将itimer与ITIMER_PROF一起使用,ITIMER_PROF仅测量当前进程所花费的cpu时间(但在用户模式和内核模式下都是如此).这意味着等待其他进程(如MysqL)不计入其中.
现在你要做的是将Linux上的itimer从ITIMER_PROF更改为ITIMER_REAL,当然你需要手动,重新编译,安装等.这两者之间的另一个区别是它们在计时器运行时也会使用不同的信号出.所以我的建议是改变ifdef:
# ifdef __CYGWIN__
成
# if 1
这样你就可以设置ITIMER_REAL和PHP等待SIGALRM的信号.
无论如何,这个想法是未经测试的(我将它用于一些非常具体的系统,其中ITIMER_PROF被破坏,似乎有效),不受支持等.使用它需要您自担风险.它本身可以与PHP本身一起使用,但如果它们出于某种原因,它可能会破坏PHP和Apache中的其他模块,使用SIGALRM信号或其他计时器.