这里有点迷路了。我正在实现自己的外壳程序,并且我需要实现的功能之一是在没有子进程运行但在有子进程运行时(例如sleep 5)忽略ctrl + c和ctrl + z它需要杀死这些进程。
我已经成功使用父级中的掩码成功阻止了SIGINT和SIGTSTP:
if ((sigemptyset(&intmask) == -1) || (sigaddset(&intmask, SIGINT) == -1) || (sigaddset(&intmask, SIGTSTP) == -1)) {
perror("invalid failed to initialize signal mask");
exit(EXIT_FAILURE);
}
signal(SIGUSR1, int_handler);
if (sigprocmask(SIG_BLOCK, &intmask, NULL) == -1) {
perror("invalid unable to block SIGINT");
exit(EXIT_FAILURE);
}
然后在孩子中,我发送一个SIGUSR1
信号:
if (fork() == 0) {
kill(cmd_group->ppid, SIGUSR1);
}
哪个正在调用信号处理程序:
void int_handler(int signum) {
if (signum == SIGUSR1) {
sigprocmask(SIG_UNBLOCK, &intmask, NULL);
}
}
当我运行sleep 5
时似乎正在调用信号处理程序,但是该过程并未以ctrl + c终止。我还应该注意,子进程位于与父进程不同的自己的进程组中。
那为什么SIGINT和SIGTSTP不能在这里畅通无阻?
编辑:
了解了信号忽略和信号阻塞之间的区别之后,我决定最好通过SIG_IGN
处理程序忽略父级中的SIGINT和SIGTSTP。
然后在子级中重置为SIG_DFL
:
父母:
int main(int argc, char* argv[]) {
signal(SIGINT, SIG_IGN);
signal(SIGTSTP, SIG_IGN);
...
}
孩子:
if (fork() == 0) {
signal(SIGINT, SIG_DFL);
signal(SIGTSTP, SIG_DFL);
// execute commands
}
对于SIGINT,它会执行所需的行为:在父级中忽略而在子级中起作用。
但是对于SIGTSTP,当我尝试杀死sleep 5
之类的子进程时,它将导致该进程永远挂起(甚至都无法从睡眠中返回)。
可能是什么原因造成的?