SIGCHLD没有陷入epoll_wait?

时间:2014-06-11 02:38:38

标签: c signals fork epoll

我想了解fork上信号的行为。我写了一个小程序用epoll_wait来捕获SIGCHLD但是当我在分叉的孩子上做“kill -9”时,我没有得到任何信号而且孩子处于已经不存在状态(我有一个执行wait()的处理程序) 。

这是代码。

//....
sigemptyset(&mask);
sigaddset(&mask, SIGCHLD);
pthread_sigmask(SIG_BLOCK, &mask, NULL);

signal_fd = signalfd(-1, &mask, 0);

memset(&tev, 0, sizeof(tev));
tev.events = EPOLLIN | EPOLLONESHOT;
tev.data.fd = signal_fd;

epoll_ctl(efd_, EPOLL_CTL_MOD, signal_fd, &tev);

while (1) {
    child_pid_ = fork();

    if (child_pid_ == 0) {
        close(signal_fd);
        close(efd_);
        make_grand_child(); //just sleeps in while(1) and never returns.
    } else {
        memset(&event, 0, sizeof(event));
        while (1) {
            epoll_wait(efd_, &event, 1, -1);
            deliver_events = (event.events & EPOLLERR|EPOLLHUP|EPOLLIN|EPOLLONESHOT);
            if (deliver_events) {
                parent_sig_handler(SIGCHLD);
                break;
            }
        }
    }
}

更新:

使用EPOLL_CTL_MOD而不先进行添加(EPOLL_CTL_ADD)。在我改变之后,它就像一个魅力。

1 个答案:

答案 0 :(得分:0)

要忽略SIGCHLD的默认处置。阻止信号不会改变处置,只会给signalfd同步处理它的机会。

使用signalsigaction为SIGCHLD添加信号处理程序。它不会做任何事情,因为它不会被执行。由于SIGCHLD被阻止,signalfd将在处理程序之前使用并处理它。