[英]Signal handler for all signal
How can I register a signal handler for ALL signal, available on the running OS, using signal(3)? 如何使用signal(3)为正在运行的操作系统上可用的ALL信号注册信号处理程序?
My code looks like this: 我的代码看起来像这样:
void sig_handler(int signum)
{
printf("Received signal %d\n", signum);
}
int main()
{
signal(ALL_SIGNALS_??, sig_handler);
while (1) {
sleep(1);
};
return 0;
}
Most systems have a macro NSIG
or _NSIG
(the former would not be available in standards-conformance mode since it violates the namespace) defined in signal.h
such that a loop for (i=1; i<_NSIG; i++)
will walk all signals. 大多数系统都有一个宏
NSIG
或_NSIG
(前者在标准一致性模式下不可用,因为它违反命名空间)在signal.h
中signal.h
,因此for (i=1; i<_NSIG; i++)
的循环将遍历所有信号。 Also, on POSIX systems that have signal masks, CHAR_BIT*sizeof(sigset_t)
is an upper bound on the number of signals which you could use as a fallback if neither NSIG
nor _NSIG
is defined. 此外,在具有信号掩码的POSIX系统上,
CHAR_BIT*sizeof(sigset_t)
是信号数量的上限,如果既未定义NSIG
也_NSIG
将其用作回退。
Signal handlers have to deal with reentrancy concerns and other problems. 信号处理程序必须处理重入问题和其他问题。 In practice, it's often more convenient to mask signals and then retrieve them from time to time.
实际上,屏蔽信号然后不时地检索它们通常更方便。 You can mask all signals (except
SIGSTOP
and SIGKILL
, which you can't handle anyway) with this: 您可以使用以下方法屏蔽所有信号(
SIGSTOP
和SIGKILL
除外,您无法处理):
sigset_t all_signals;
sigfillset(&all_signals);
sigprocmask(SIG_BLOCK, &all_signals, NULL);
The code is slightly different if you're using pthreads. 如果你使用pthreads,代码会略有不同。 Call this in every thread, or (preferably) in the main thread before you create any others:
在创建任何其他线程之前,或者(最好)在主线程中调用此函数:
sigset_t all_signals;
sigfillset(&all_signals);
pthread_sigmask(SIG_BLOCK, &all_signals, NULL);
Once you've done that, you should periodically call sigtimedwait(2)
like this: 一旦你完成了,你应该定期调用
sigtimedwait(2)
如下所示:
struct timespec no_time = {0, 0};
siginfo_t result;
int rc = sigtimedwait(&all_signals, &result, &no_time);
If there is a signal pending, information about it will be placed in result
and rc
will be the signal number; 如果有信号待处理,有关它的信息将被放入
result
, rc
将是信号编号; if not, rc
will be -1 and errno
will be EAGAIN
. 如果没有,
rc
将为-1,而errno
将为EAGAIN
。 If you're already calling select(2)
/ poll(2)
(eg as part of some event-driven system), you may want to create a signalfd(2)
instead and attach it to your event loop. 如果您已经调用了
select(2)
/ poll(2)
(例如,作为某些事件驱动系统的一部分),您可能需要创建一个signalfd(2)
并将其附加到您的事件循环中。 In this case, you still need to mask the signals as shown above. 在这种情况下,您仍然需要屏蔽信号,如上所示。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.