#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);
```