我怎么能确定在使用pause()时我没有丢失信号?

Nog*_*oga 3 c linux signals

我正在编写一个程序,它使用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)

Mil*_*lan 5

建议使用sigaction而不是signal,但在这两种情况下都不能提供你需要的东西.如果孩子在前一个信号仍在处理时发送信号,它将成为待处理信号,但如果发送的信号越多,它们将被丢弃(在没有阻塞输入信号的系统上,信号可以在重新建立之前传送)处理程序并再次导致信号丢失).没有解决方法.

通常做的是假设缺少一些信号,并让处理程序照顾退出的孩子.

在您的情况下,不要发送孩子的信号,而是让孩子们终止.一旦终止,父进程的SIGCHLD处理程序应该用来收获它们.使用waitpidWNOHANG选项可确保父项将捕获所有子项,即使它们都同时终止.

例如,计算已退出子项数的SIGCHLD处理程序可以是:

 pid_t pid;

 while((pid = waitpid(-1, NULL, WNOHANG)) > 0) {
       nrOfChildrenHandled++;
 }
Run Code Online (Sandbox Code Playgroud)