2013-11-09 59 views
1

我有两个处理程序(SIGTSTP,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。
susp表示如果该进程被暂停或停止,则“粉碎”父进程的状态。

+0

看来,用正确的标志,你可以告诉哪个孩子被暂停,以及它收到了哪个信号。所以这不仅可以让你检测到实际的退出,还可以采取一些行动来暂停/恢复。 –

回答

2

使用sigactionSA_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但付出的代价几个不同的选项和行为在弄清楚如何使用它之前,需要考虑复杂性和混淆性。我尽可能少地猜出了你似乎想做的事情,但你需要尽早而不是晚些时候学习。

+0

你能举个例子吗?谢谢 – Rawhi

+0

顺便说一下,尽管SA_NOCLDSTOP在* nix平台上可用,它依赖于实现,可能无法在所有平台上按预期工作。它适用于Linux。 – Duck

相关问题