目标是阻止 Apache httpd 进程,直到 15 秒或另一个进程发出 SIGUSR1 信号。被阻止进程的进程ID存储在其他进程可以访问的数据库中。我正在使用 pselect()/kill() 函数来尝试执行此操作。
从我的日志中,我知道
kill(pid, SIGUSR1)
是在 15 秒超时之前执行的,并且使用了正确的 pid。然而,pselect()
总是超时(尽管发送了SIGUSR1)。
这在 Apache HTTP 服务器架构中根本不可能吗?
以下是被阻止进程的代码片段,以及尝试解除阻止的进程。
savePid(getpid());
struct timespec t = {15, 0};
sigset_t mask;
sigemptyset(&mask);
sigaddset(&mask, SIGUSR1);
res = pselect(0, NULL, NULL, NULL, &t, &mask);
if (res == 0) {
/*
* timeout
*/
...
} else {
/*
* interrupted
*/
...
}
另一个进程决定“解除阻止”在 pselect 中阻止的进程,并发出
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"
经过更多测试,我发现这个有效:
函数 dummy_handler 不执行任何操作:
static void dummy_handler() { }
```
struct timespec t = {15, 0};
struct sigaction sa;
sa.sa_handler = dummy_handler;
sigemptyset(&sa.sa_mask);
sigaction(SIGUSR1, &sa, NULL);
res = pselect(0, NULL, NULL, NULL, &t, &sa.sa_mask);
```