5

如何使用 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;
}
4

2 回答 2

7

大多数系统都有一个宏NSIG_NSIG(前者在标准一致性模式下不可用,因为它违反了命名空间)定义signal.h为循环for (i=1; i<_NSIG; i++)将遍历所有信号。此外,在具有信号掩码的 POSIX 系统上,如果既未定义也未定义CHAR_BIT*sizeof(sigset_t),您可以将其用作后备信号数量的上限。NSIG_NSIG

于 2013-06-22T23:37:00.943 回答
3

信号处理程序必须处理重入问题和其他问题。在实践中,屏蔽信号然后不时检索它们通常更方便。您可以使用以下方法屏蔽所有信号(除了SIGSTOPand 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)替代并将其附加到您的事件循环中。在这种情况下,您仍然需要如上所示屏蔽信号。

于 2014-11-14T15:08:08.523 回答