所有信号的信号处理程序

时间:2013-06-22 22:07:42

标签: c linux unix signal-handling

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

2 个答案:

答案 0 :(得分:5)

大多数系统在NSIG中定义了一个宏_NSIGsignal.h(前者在标准一致性模式中不可用,因为它违反了命名空间),因此循环{{ 1}}将走所有信号。此外,在具有信号掩码的POSIX系统上,for (i=1; i<_NSIG; i++)是信号数量的上限,如果未定义CHAR_BIT*sizeof(sigset_t)NSIG,则可以将其用作回退。

答案 1 :(得分:3)

信号处理程序必须处理重入问题和其他问题。在实践中,屏蔽信号然后不时地检索信号通常更方便。您可以使用以下功能屏蔽所有信号(SIGSTOPSIGKILL除外,您无法处理):

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)并将其附加到您的事件循环中。在这种情况下,您仍然需要屏蔽信号,如上所示。