Apache模块中的静态变量初始化多次?

时间:2011-05-09 09:25:23

标签: c apache module apache2 global-variables

我为Apache HTTP服务器编写了一个模块,发现了奇怪的行为。我假设静态变量只初始化了一次,但是我编写了下面的代码并向Apache发出了两个请求输出:


test_handler: isInit=0
test_handler: isInit=1

test_handlere: isInit=0
test_handlere: isInit=1

测试代码:


static int isInit = 0;

static int test_handler( request_rec *r ) {
    fprintf(stderr,"\n\natest_handler: isInit=%d", isInit );
    if( !isInit ) {
        isInit = 1;
    }
    fprintf(stderr,"\natest_handler: isInit=%d", isInit );
    fflush(stderr);
    return DECLINED;
}

static void register_hooks(apr_pool_t *p) {
    fprintf(stdout,"register_hooks\n"); 
    ap_hook_translate_name(test_handler, NULL, NULL, APR_HOOK_FIRST);    
    fprintf(stdout,"register_hooks done\n");
}

module AP_MODULE_DECLARE_DATA test_module = {
    STANDARD20_MODULE_STUFF, 
    NULL,                  /* create per-dir    config structures */
    NULL,                  /* merge  per-dir    config structures */
    NULL,                  /* create per-server config structures */
    NULL,                  /* merge  per-server config structures */
    NULL,                  /* table of config file commands       */
    register_hooks  /* register hooks                      */
};

与线程相关的问题,因为当我向Apache发出10个请求时,我在某些情况下会看到isInit=1, isInit=1,而在其他情况下看到isInit=0, isInit=1

我的问题是,我如何定义变量,可以在test_handler()中访问,并在函数调用之间保留其值?

2 个答案:

答案 0 :(得分:2)

我想,我发现了问题。 Apache Server for Linux创建了几个“子”服务器来提供paralel请求。每个虚拟服务器都会加载配置,包括模块即时,因此如果ApacheServer创建了8个子服务器进程,那么您将获得8个isInit变量副本。您可以配置Apache以创建obly一个服务器(不推荐 - 性能)。另一种方法是将Apache服务器配置为使用其他Multi-Proccess技术,我读了preot prefork和worker。根据Windows上的Apache2文档,服务器使用Windows API,因此您可以迁移到Windows或编写可以作为多个并行实例的模块。

答案 1 :(得分:1)

我认为它可能与多个线程同时运行时发生的竞争条件有关。关键字static仅限制变量的范围,因此它不是解决方案 - 使用类似mutexes的内容来排除竞争条件。谈到在连接中的函数调用之间保留一些变量,您需要将此变量存储在与连接相关的结构中(例如,请参阅request_rec->notesrequest_rec->connection->notes)。