我为每一个(SIGTSTP,SIGCHLD)都有两个处理程序,就是当我使用SIGTSTP暂停一个进程时,SIGCHLD的处理函数也会运行。我该怎么做才能防止这种情况发生。
信号处理程序:
void signalHandler(int signal) {
int pid, cstatus;
if (signal == SIGCHLD) {
susp = 0;
pid = waitpid(-1, &cstatus, WNOHANG);
printf("[[child %d terminated]]\n", pid);
DelPID(&JobsList, pid);
}
}
void ctrlZsignal(int signal){
kill(Susp_Bg_Pid, SIGTSTP);
susp = 0;
printf("\nchild %d suspended\n", Susp_Bg_Pid);
}
Susp_Bg_Pid用于保存暂停的进程ID。
如果父进程被暂停,则表示“粉碎”父进程的状态。
答案 0 :(得分:4)
使用sigaction
SA_NOCLDSTOP
设置SIGCHLD处理程序。
来自sigaction(2)
SA_NOCLDSTOP - 如果signum是SIGCHLD,当子进程停止时(即,当他们收到SIGSTOP,SIGTSTP,SIGTTIN或SIGTTOU之一)或恢复时(即他们收到SIGCONT),请不要收到通知(参见wait(2)) 。该标志仅在为SIGCHLD建立处理程序时有意义。
<强>更新强>
void signalHandler(int sig)
{
//...
}
struct sigaction act;
act.sa_handler = signalHandler;
sigemptyset(&act.sa_mask);
act.sa_flags = SA_NOCLDSTOP;
if (sigaction(SIGCHLD, &act, 0) == -1)
{
perror("sigaction");
exit(1);
}
如果你不熟悉sigaction
,你应该阅读它,因为它有几个不同的选项和行为,远远优于signal
但是以你的复杂性和混乱为代价弄清楚如何使用它。我把你最好的猜测放在了你想要做的事情的最起码上,但是你需要尽快学习它。