0

在 max_execution_time 的文档中,我们读到

在确定脚本运行的最长时间时,不包括在脚本执行之外发生的活动所花费的任何时间,例如使用 system() 的系统调用、流操作、数据库查询等。

如果这是真的,那么简单地按照确定到目前为止 PHP 执行了多长时间中的建议使用微时间不会给您任何关于您与最大执行时间限制的接近程度的任何线索。

在某些环境/语言中存在“软”限制的概念——当它达到时,应用程序会收到通知,但不会终止,并且可以优雅地做出反应。在我看来,在 PHP 中你只有一个“硬”限制——你要么在截止日期之前,要么因为“超过 %d 秒%s 的最大执行时间”E_ERROR 而撞墙,你什么也做不了关于。

我想做的是不时检查脚本到目前为止执行了多长时间,并在接近最大执行时间时手动处理优雅退出。

在一个类似的问题Detect when running time is near max_execution_time由类似问题引起,接受的解决方案是注册一个关闭函数——这在某种程度上回避了原始问题,并不真正适用于我的情况——我想处理这个问题在应用程序上下文中,而不是在关闭处理程序中。

据我了解 Zend/zend_execute_API.c 的 zend_set_timeout 函数使用 struct itimerval t_r; /* 请求超时 */ sigset_t sigset;

            if(seconds) {
                    t_r.it_value.tv_sec = seconds;
                    t_r.it_value.tv_usec = t_r.it_interval.tv_sec = t_r.it_interval.tv_usec = 0;
                    setitimer(ITIMER_PROF, &t_r, NULL);
            }
            if(reset_signals) {
                    signal(SIGPROF, zend_timeout);
                    sigemptyset(&sigset);
                    sigaddset(&sigset, SIGPROF);
            }

据我了解http://linux.die.net/man/2/setitimer这应该同时测量:用户和系统模式时间。我在这里感到困惑,因为它与 PHP 规范有些矛盾。在 setitimer 的注释中可以读到

POSIX.1 未指定 setitimer() 与三个接口 alarm(2)、sleep(3) 和 usleep(3) 之间的交互。

这可以解释为什么以下脚本在 5(挂钟)秒后不退出:

<?php
set_time_limit(5);
while(1){sleep(1);}
?>

可能睡眠不计入用户时间或系统时间。

4

0 回答 0