+ -
当前位置:首页 → 问答吧 → PHP的超时实现

PHP的超时实现

时间:2013-03-29

来源:互联网

本帖最后由 liexusong 于 2013-3-29 15:04 编辑

    我们知道PHP可以设置一个脚本执行的超时时间, 也就是脚本的执行时间不能超过设置的超时时间.
那么PHP是怎么做到这个功能的呢?

    其实PHP的超时功能利用了操作系统的定时信号来实现的, 在一个请求开始时(php_request_startup),
PHP便会利用zend_set_timeout()接口来设置一个定时器信号, zend_set_timeout()的实现如下:
void zend_set_timeout(long seconds)
{
    ......
    setitimer(ITIMER_REAL, &t_r, NULL);
    signal(SIGALRM, zend_timeout);
    sigemptyset(&sigset);
    sigaddset(&sigset, SIGALRM);
    ......
}


    可以看出, zend_set_timeout()主要是调用了操作系统的setitimer()接口来设置定时器信号,  
然后使用signal()接口来设置定时器信号的处理回调函数为zend_timeout().
    而在php_request_startup()函数中可以看到以下的调用:

int php_request_startup(TSRMLS_D)
{
    ......
    zend_set_timeout(EG(timeout_seconds));
    ......
}


    当一个客户端请求到达的时候, PHP便会调用php_request_startup()函数, 而php_request_startup()
函数就会调用zend_set_timeout()来设置定时器信号, 当定时器信号触发的时候, 便会调用zend_timeout()
函数, zend_timeout()函数如下:

ZEND_API void zend_timeout(int dummy)
{
    ......
    zend_error(E_ERROR, "Maximum execution time of %d second%s exceeded",
 EG(timeout_seconds), EG(timeout_seconds) == 1 ? "" : "s");
    ......
}


    可以看出, zend_timeout()函数主要就是调用zend_error()函数, 而zend_error()函数的作用主要是
输出超时提示和结束请求, 也就是类似于echo加exit一样.

作者: liexusong   发布时间: 2013-03-29

{:soso_e113:} 曼曼你终于回来啦~~

好东西,又科普了下.

作者: 刹那芳华网   发布时间: 2013-03-29

支持分享,拜读了楼主的大作,是PHPER进阶好书。

作者: hooi   发布时间: 2013-03-29

{:soso_e179:}

作者: webdna   发布时间: 2013-04-16

在和nginx搭配使用的时候php的超时还严重依赖于nginx的超时设定,否则nginx没有设定好,php一样还是会超时

作者: qxhy123   发布时间: 2013-04-20

qxhy123 发表于 2013-4-20 22:47
在和nginx搭配使用的时候php的超时还严重依赖于nginx的超时设定,否则nginx没有设定好,php一样还是会超时 ...

严重同意
nginx.conf里面主要是如下

fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;

php-fpm.conf里如要是如下

request_terminate_timeout = 10s

作者: hooi   发布时间: 2013-05-07