【问题标题】:How can I be sure I'm not losing signals when using pause()?如何确保在使用 pause() 时不会丢失信号?
【发布时间】:2011-03-21 12:26:55
【问题描述】:

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

【问题讨论】:

    标签: c linux signals


    【解决方案1】:

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

    通常的做法是假设某些信号丢失,并让处理程序处理退出的子进程。

    在您的情况下,不要从您的孩子那里发送信号,而是让孩子终止。一旦它们终止,应该使用父级的 SIGCHLD 处理程序来获取它们。将waitpid 与 WNOHANG 选项一起使用可确保父级将捕获所有子级,即使它们都同时终止。

    例如,计算退出子节点数量的 SIGCHLD 处理程序可以是:

     pid_t pid;
    
     while((pid = waitpid(-1, NULL, WNOHANG)) > 0) {
           nrOfChildrenHandled++;
     }
    

    【讨论】:

    • 感谢您的回答。但这并不是我想要的。我不想等待()我的孩子,直到他们都完成。
    • 如果我将 sigaction 与 SA_NODEFER 一起使用会安全吗?文档说:SA_NODEFER 不要阻止从其自己的信号处理程序中接收信号。
    • 将 sigaction 与选项一起使用将调用处理程序,即使它正在处理另一个信号。但是根据调用处理程序的时间,当同时发送多个信号时,您可能会在处理程序执行期间丢失信息。您可以按照 ubiquite 的建议使用实时信号,但您可以做什么也有限制。信号不是事件驱动的框架。基本上,您需要重新考虑自己在做什么,因为信号不应该以这种方式使用。
    【解决方案2】:

    为避免这种情况,您可以使用 posix real-time signals

    【讨论】:

      【解决方案3】:

      使用 sigaction 代替信号来注册你的处理程序,并且信号的传递是有保证的。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-12-21
        • 1970-01-01
        • 2014-05-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多