Синхронизация процессов Apache

#c #apache #select #signals #interprocess

Вопрос:

Цель состоит в том, чтобы заблокировать процесс Apache httpd до тех пор, пока либо 15 секунд, либо другой процесс не выдаст сигнал SIGUSR1. Идентификатор процесса заблокированного процесса хранится в базе данных, к которой могут получить доступ другие процессы. Я использую функции pselect()/kill (), чтобы попытаться сделать это.

Из моих журналов я знаю kill(pid, SIGUSR1) , что он выполняется до истечения 15-секундного тайм-аута и использует правильный pid. Однако время pselect() ожидания всегда истекает (несмотря на отправку SIGUSR1).

Неужели это просто невозможно в архитектуре HTTP-сервера Apache?

Вот фрагменты кода заблокированного процесса и процесса, пытающегося его разблокировать.

 savePid(getpid());
struct timespec t = {15, 0};
sigset_t mask;
sigemptyset(amp;mask);
sigaddset(amp;mask, SIGUSR1);
res = pselect(0, NULL, NULL, NULL, amp;t, amp;mask);
if (res == 0) {
        /*
         *  timeout
         */
        ...
} else {
       /*
        * interrupted
        */
        ...
}
 

Другой процесс решил «разблокировать» процесс, заблокированный в выборе, и выдает

 pid = getStoredPid();
kill(pid, SIGUSR1)
 
 Apacher Server Information:
Server version: Apache/2.4.41 (Unix)
Server built:   Aug  3 2020 16:34:41
Server's Module Magic Number: 20120211:88
Server loaded:  APR 1.7.0, APR-UTIL 1.6.1
Compiled using: APR 1.7.0, APR-UTIL 1.6.1
Architecture:   64-bit
Server MPM:     prefork
  threaded:     no
    forked:     yes (variable process count)
Server compiled with....
 -D APR_HAS_SENDFILE
 -D APR_HAS_MMAP
 -D APR_HAVE_IPV6 (IPv4-mapped addresses enabled)
 -D APR_USE_PROC_PTHREAD_SERIALIZE
 -D APR_USE_PTHREAD_SERIALIZE
 -D SINGLE_LISTEN_UNSERIALIZED_ACCEPT
 -D APR_HAS_OTHER_CHILD
 -D AP_HAVE_RELIABLE_PIPED_LOGS
 -D DYNAMIC_MODULE_LIMIT=256
 -D HTTPD_ROOT="/usr"
 -D SUEXEC_BIN="no"
 -D DEFAULT_PIDLOG="/var/logs/httpd.pid"
 -D DEFAULT_SCOREBOARD="logs/apache_runtime_status"
 -D DEFAULT_ERRORLOG="logs/error_log"
 -D AP_TYPES_CONFIG_FILE="/etc/apache/mime.types"
 -D SERVER_CONFIG_FILE="/etc/apache/httpd.conf"
 

Комментарии:

1. Вы пробовали отправлять сигналы SIGSTOP и SIGCONT в процесс apache?

2. Как вы думаете, что делает аргумент маски для выбора ? Что говорится об этом на главной странице?

Ответ №1:

После еще небольшого тестирования я обнаружил, что это работает:

Функция dummy_handler ничего не делает: static void dummy_handler() { }

 ```
struct timespec t = {15, 0};
struct sigaction sa;
sa.sa_handler = dummy_handler;
sigemptyset(amp;sa.sa_mask);
sigaction(SIGUSR1, amp;sa, NULL);
res = pselect(0, NULL, NULL, NULL, amp;t, amp;sa.sa_mask);
```