如何使用 signal(3) 为正在运行的操作系统上可用的 ALL 信号注册信号处理程序?
我的代码如下所示:
void sig_handler(int signum)
{
printf("Received signal %d\n", signum);
}
int main()
{
signal(ALL_SIGNALS_??, sig_handler);
while (1) {
sleep(1);
};
return 0;
}
如何使用 signal(3) 为正在运行的操作系统上可用的 ALL 信号注册信号处理程序?
我的代码如下所示:
void sig_handler(int signum)
{
printf("Received signal %d\n", signum);
}
int main()
{
signal(ALL_SIGNALS_??, sig_handler);
while (1) {
sleep(1);
};
return 0;
}
大多数系统都有一个宏NSIG
或_NSIG
(前者在标准一致性模式下不可用,因为它违反了命名空间)定义signal.h
为循环for (i=1; i<_NSIG; i++)
将遍历所有信号。此外,在具有信号掩码的 POSIX 系统上,如果既未定义也未定义CHAR_BIT*sizeof(sigset_t)
,您可以将其用作后备信号数量的上限。NSIG
_NSIG
信号处理程序必须处理重入问题和其他问题。在实践中,屏蔽信号然后不时检索它们通常更方便。您可以使用以下方法屏蔽所有信号(除了SIGSTOP
and SIGKILL
,您无论如何都无法处理):
sigset_t all_signals;
sigfillset(&all_signals);
sigprocmask(SIG_BLOCK, &all_signals, NULL);
如果您使用 pthreads,代码会略有不同。在创建任何其他线程之前,在每个线程或(最好)在主线程中调用它:
sigset_t all_signals;
sigfillset(&all_signals);
pthread_sigmask(SIG_BLOCK, &all_signals, NULL);
完成此操作后,您应该定期sigtimedwait(2)
像这样调用:
struct timespec no_time = {0, 0};
siginfo_t result;
int rc = sigtimedwait(&all_signals, &result, &no_time);
如果有信号未决,有关它的信息将被放置在result
信号rc
编号中;如果不是,rc
将是 -1 并且errno
将是EAGAIN
. 如果您已经在调用select(2)
/ poll(2)
(例如,作为某些事件驱动系统的一部分),您可能需要创建一个signalfd(2)
替代并将其附加到您的事件循环中。在这种情况下,您仍然需要如上所示屏蔽信号。