简体   繁体   English

所有信号的信号处理程序

[英]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.hsignal.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: 您可以使用以下方法屏蔽所有信号( SIGSTOPSIGKILL除外,您无法处理):

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; 如果有信号待处理,有关它的信息将被放入resultrc将是信号编号; 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM