我正在编写一个程序,它使用fork来创建子进程,并在完成后对它们进行计数.我怎么能确定我没有丢失信号?如果孩子在主程序仍然处理前一个信号时发送信号,会发生什么?是"丢失"的信号?我怎么能避免这种情况?
void my_prog()
{
for(i = 0; i<numberOfDirectChildrenGlobal; ++i) {
pid = fork();
if(pid > 0)//parent
//do parent thing
else if(0 == pid) //child
//do child thing
else
//exit with error
}
while(numberOfDirectChildrenGlobal > 0) {
pause(); //waiting for signal as many times as number of direct children
}
kill(getppid(),SIGUSR1);
exit(0);
}
void sigUsrHandler(int signum)
{
//re-register to SIGUSR1
signal(SIGUSR1, sigUsrHandler);
//update number of children that finished
--numberOfDirectChildrenGlobal;
}
Run Code Online (Sandbox Code Playgroud)
建议使用sigaction而不是signal,但在这两种情况下都不能提供你需要的东西.如果孩子在前一个信号仍在处理时发送信号,它将成为待处理信号,但如果发送的信号越多,它们将被丢弃(在没有阻塞输入信号的系统上,信号可以在重新建立之前传送)处理程序并再次导致信号丢失).没有解决方法.
通常做的是假设缺少一些信号,并让处理程序照顾退出的孩子.
在您的情况下,不要发送孩子的信号,而是让孩子们终止.一旦终止,父进程的SIGCHLD处理程序应该用来收获它们.使用waitpidWNOHANG选项可确保父项将捕获所有子项,即使它们都同时终止.
例如,计算已退出子项数的SIGCHLD处理程序可以是:
pid_t pid;
while((pid = waitpid(-1, NULL, WNOHANG)) > 0) {
nrOfChildrenHandled++;
}
Run Code Online (Sandbox Code Playgroud)