当你发现你不能调用SIG_DFL和SIG_IGN 本身 。但是,您可以或多或少模仿它们的行为。
简而言之,模仿正常信号处理将是:
- 用户定义的
sa_handler
s 很容易 - 对于SIG_IGN来说足够简单,需要注意的是,对于CHLD,您需要waitpid()
- 简单但对SIG_DFL却不愉快,因此重新提高了内核的魔力。
这是您想要的吗?
#include <signal.h>#include <stdlib.h>void dispatch_signal(const int signo) { int stop = 0; sigset_t oset; struct sigaction curact; sigaction(signo, NULL, &curact); if (SIG_IGN == curact.sa_handler) { if (SIGCHLD == signo) { int status; while (waitpid(-1, &status, WNOHANG|WUNTRACED) > 0) {;} } return; } if (SIG_DFL != curact.sa_handler) { curact.sa_handler(signo); return; } if (SIGURG == signo || SIGWINCH == signo || SIGCONT == signo) return; stop = (SIGTSTP == signo || SIGTTIN == signo || SIGTTOU == signo); if (stop) { sigset_t sig_cont; sigemptyset(&sig_cont); sigaddset(&sig_cont, SIGCONT); sigprocmask(SIG_UNBLOCK, &sig_cont, &oset); } kill(getpid(), signo); if (stop) sigprocmask(SIG_SETMASK, &oset, NULL);}更新 (针对OP的精彩问题)
1:此插槽是否在sigwaitinfo之后?
是。就像是:
... block signals ...signo = sigwaitinfo(&set, &info);dispatch_signal(signo);
2:为什么不引发那些由SIG_IGN处理的信号,无论如何它们都会被忽略
与三个系统调用(重新引发,取消屏蔽,重新屏蔽)相比,在用户空间中进行noop效率更高。此外,当SIG_IGNored时,CHLD具有特殊的语义。
3:为什么要特别对待SIGCHLD?
最初(检查答案是否编辑)我没有-在SIG_IGN情况下重新提出,因为IGNored
CHLD信号告诉内核自动获得子级。
但是,我进行了更改,因为“自然的”
CHLD信号携带有关终止过程的信息(至少PID,状态和实际UID)。用户生成的CHLD信号不具有相同的语义,在我的测试中,对它们进行IGNoring不会导致2.6自动收起SIGCHLD被“遗漏”的排队的僵尸。所以,我自己做。
4:为什么与“停止”相关的信号会阻止CONT。 不会为CONT调用默认的处理程序吗?
如果我们停止(不执行)并且CONT被阻止,我们将永远不会收到唤醒我们的信号!
5:为什么不叫加注而不是加注的底线?
个人喜好;
raise()也可以。



