C语言 重新注册信号处理程序会导致无限循环



使用以下信号处理程序,按Ctrl-C会导致重复调用处理程序,我不知道为什么:

(警告:如果您键入Ctrl-C,则必须使用kill <pid>退出程序)

static void handler(int sig) {
// do something interesting
// write so I can see if I'm in an infinite loop
write(1, "A", 1);
// raise normal signal behavior
// this ensures normal signal behavior
// for example, exiting with code 130 if Ctrl-C is used
signal(sig, SIG_DFL);
raise(sig);
// re-register handler
// that way, if signal doesn't exit the program and the signal
//   is sent again in the future, this handler will run again
signal(sig, handler);
}

所以我知道我对信号处理程序有些不了解。我假设只有SIGCONT会到达最后一行,因为SIGINT(例如),当它以默认行为(SIG_DFL)引发时,应该退出而不是返回。

我也知道我可以将最后一行包装在 if 语句中,该语句仅适用于SIGCONT,但我真的很想知道为什么它的行为方式不符合我的预期。

问题

  1. 为什么信号处理程序在无限循环中被调用?
  2. 如何让处理程序执行有趣的操作,调用默认行为,然后在默认行为未退出程序的情况下重新注册自身?

MCVE

这可以通过将它写入文件sigtest.c并执行make sigtest来运行。使用Ctrl-C提高SIGINT,并在另一个终端中,准备做ps | grep sigtest然后kill <pid>

#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
static void handler(int sig) {
// do something interesting
// write so I can see if I'm in an infinite loop
write(1, "A", 1);
// raise normal signal behavior
// this ensures normal signal behavior
// for example, exiting with code 130 if Ctrl-C is used
signal(sig, SIG_DFL);
raise(sig);
// re-register handler
// that way, if signal doesn't exit the program and the signal
//   is sent again in the future, this handler will run again
signal(sig, handler);
}
int main(void) {
char c;
signal(SIGINT, handler);
signal(SIGTSTP, handler);
signal(SIGCONT, handler);
printf("type 'x' and 'Enter' to exitn");
while (1) {
c = getchar();
printf("got char: %cn", c);
if (c == 'x') { break; }
}
}

我空白了,忘记了信号在处理时被阻止了。这意味着在处理程序返回之前,并且在我将操作从SIG_DFL设置回自定义处理程序之前,实际上不会引发SIGINT。因此,它是循环的。

我的示例的工作处理程序如下所示:

static void handler(int sig) {
if (sig == SIGCONT) {
// do something interesting
signal(sig, handler);
signal(SIGTSTP, handler);
} else {
// do something else interesting
signal(sig, SIG_DFL);
raise(sig);
}
}

最新更新