首页 文章

处理多个SIGCHLD

提问于
浏览
16

在运行Linux 2.6.35的系统中,我的程序会创建许多子进程并监视它们 . 如果子进程死亡,我会进行一些清理并再次生成进程 . 我使用 signalfd() 来获取我的进程中的 SIGCHLD 信号 . signalfd 使用 libevent 异步使用 .

当使用信号处理程序用于非实时信号时,当信号处理程序针对特定信号运行时,必须阻止进一步发生相同信号以避免进入递归处理程序 . 如果此时多个信号到达,则内核仅调用一次处理程序(当信号被解除阻塞时) .

使用 signalfd() 时是否也是相同的行为?由于基于 signalfd 的处理没有与正常信号处理程序的异步执行相关的典型问题,我认为内核可以排队 SIGCHLD 的所有进一步出现?

任何人都可以澄清这种情况下的Linux行为......

2 回答

  • 19

    在Linux上,在您使用 signalfd() 读取 SIGCHLD 之前终止的多个子节点将被压缩为单个 SIGCHLD . 这意味着当您阅读 SIGCHLD 信号时,您必须在所有已终止的孩子之后进行清理:

    // Do this after you've read() a SIGCHLD from the signalfd file descriptor:
    while (1) {
        int status;
        pid_t pid = waitpid(-1, &status, WNOHANG);
        if (pid <= 0) {
            break;
        }
        // something happened with child 'pid', do something about it...
        // Details are in 'status', see waitpid() manpage
    }
    

    我应该注意到,当两个子进程同时终止时,我实际上看到了这种信号压缩 . 如果我只做了一个 waitpid() ,其中一个终止的孩子没有被处理;并且上面的循环修复了它 .

    相应文件:

  • 0

    实际上,无障碍的方式是 waitfd 功能,允许您向poll()/ epoll()添加特定的pid . 不幸的是,多年前它被提出时并未被Linux接受 .

相关问题