我正在编写一个程序,它使用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;
}
答案 0 :(得分:5)
建议使用sigaction而不是signal,但在这两种情况下它都不会提供你需要的东西。如果孩子在前一个信号仍在处理时发送信号,它将成为待处理信号,但如果发送的信号越多,它们将被丢弃(在没有阻塞输入信号的系统上,信号可以在重新建立之前传送)处理程序并再次导致信号丢失)。没有解决方法。
通常做的是假设缺少某些信号,并让处理程序负责退出的孩子。
在您的情况下,不要发送孩子的信号,而是让孩子们终止。一旦终止,父进程的SIGCHLD处理程序应该用来收获它们。使用带有WNOHANG选项的waitpid
可确保父级将捕获所有子级,即使它们都同时终止。
例如,计算已退出子项数的SIGCHLD处理程序可以是:
pid_t pid;
while((pid = waitpid(-1, NULL, WNOHANG)) > 0) {
nrOfChildrenHandled++;
}
答案 1 :(得分:0)
使用sigaction而不是signal来注册您的处理程序,并确保信号的传递。
答案 2 :(得分:0)
要避免这种情况,您可以使用posix real-time signals。