SIGTSTP和SIGCHLD之间有什么关系

时间:2013-11-09 21:48:27

标签: c linux signals posix sigchld

我为每一个(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。
如果父进程被暂停,则表示“粉碎”父进程的状态。

1 个答案:

答案 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但是以你的复杂性和混乱为代价弄清楚如何使用它。我把你最好的猜测放在了你想要做的事情的最起码上,但是你需要尽快学习它。