Статические переменные в модуле Apache инициализируются более одного раза? - PullRequest
1 голос
/ 09 мая 2011

Я написал модуль для HTTP-сервера Apache и обнаружил странное поведение.Я предположил, что статические переменные инициализируются только один раз, но я написал приведенный ниже код и сделал два запроса к 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                      */
};

Проблема связана с потоками, так как, когда я делаю 10 запросов к Apache, я вижу isInit=1, isInit=1 в некоторых случаях и isInit=0, isInit=1 в других.

У меня такой вопрос, как я могу определить переменную, чтобудет доступен в test_handler() и сохранит свое значение между вызовами функции?

Ответы [ 2 ]

2 голосов
/ 12 мая 2011

Я думаю, я нашел проблему. Apache Server для Linux создает несколько «дочерних» серверов для обслуживания параллельных запросов. Каждый виртуальный сервер загружает конфигурацию, включая моментальные моменты модулей, поэтому, если ApacheServer создает 8 дочерних процессов сервера, вы получаете 8 копий переменной isInit. Вы можете настроить Apache для создания только одного сервера (не рекомендуется - производительность). Другой способ - настроить Apache Server на использование других технологий Multi-Proccess, я прочитал abot prefork и worker. Согласно документации Apache2 для Windows, сервер использует Windows API, поэтому вы можете перейти на Windows или написать модуль, который может работать как несколько экземпляров paralel.

1 голос
/ 09 мая 2011

Я думаю, что это может быть связано с состоянием гонки, которое возникает, когда несколько потоков работают одновременно.Ключевое слово static только ограничивает область действия переменной, поэтому оно не является решением - используйте что-то вроде mutexes с целью исключения условия гонки.Говоря о хранении некоторой переменной между вызовами функций в соединении, вам нужно будет сохранить эту переменную в структурах, связанных с соединением (см., Например, request_rec->notes или request_rec->connection->notes).

...