PHP后台守护进程的实现

来源:互联网 发布:防范电信网络诈骗宣传 编辑:程序博客网 时间:2024/05/18 02:23
使用场景:用户触发守护进程,并以守护进程的方式在后台执行一些计划任务。

定义与用法:

主要使用PHP内置ignore_user_abort函数来完成,函数设置与客户机断开是否会终止脚本的执行函数返回 user-abort 设置的之前的值(一个布尔值);

语法

ignore_user_abort(setting)

参数描述setting

可选。如果设置为 true,则忽略与用户的断开,如果设置为 false,会导致脚本停止运行。

如果未设置该参数,会返回当前的设置。


提示和注释

注释:PHP 不会检测到用户是否已断开连接,直到尝试向客户机发送信息为止。简单地使用 echo 语句无法确保信息发送,参阅 flush() 函数。

示例:

<?php//忽略用户的停止信号,并一直执行ignore_user_abort(true);set_time_limit(0);while(1){    //连接失败    if(connection_status() != CONNECTION_NORMAL)    {        break;//停止守护进程    }    //...do something...        //十秒钟执行一次    sleep(10);}?>

查看函数源码,发现只是改变了变量ignore_user_abort的值,代码如下:

PHP_FUNCTION(ignore_user_abort){char *arg = NULL;int arg_len = 0;int old_setting;if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &arg, &arg_len) == FAILURE) {return;}old_setting = PG(ignore_user_abort);        if (arg) {                 //设置ignore_user_abort的值zend_alter_ini_entry_ex("ignore_user_abort", sizeof("ignore_user_abort"), arg, arg_len, PHP_INI_USER, PHP_INI_STAGE_RUNTIME, 0 TSRMLS_CC);}RETURN_LONG(old_setting);}

继续跟踪到main.c,找到函数php_handle_aborted_connection,发现ignore_user_abort为false时,则调用zend_bailout退出当前执行的代码,反之则继续执行

PHPAPI void php_handle_aborted_connection(void){TSRMLS_FETCH();PG(connection_status) = PHP_CONNECTION_ABORTED;php_output_set_status(0 TSRMLS_CC);//没有设置ignore_user_abort变量为true,则中止执行if (!PG(ignore_user_abort)) {zend_bailout();}}

同样,在mod_php5API函数接口中可以找到sapi_apache_ub_write,其中ub是unbuffer的意思,此函数是apache在向客户端写数据超时的调用的

static int sapi_apache_ub_write(const char *str, uint str_length TSRMLS_DC){int ret=0;if (SG(server_context)) {ret = rwrite(str, str_length, (request_rec *) SG(server_context));}if (ret != str_length) {php_handle_aborted_connection();}return ret;}

所以从ignore_user_abort的函数定义一层层深入进来,不难发现其中的实现其中的实现
参考资料: http://cn.php.net/manual/zh/function.ignore-user-abort.php