【问题标题】:SIGCHLD not caught in epoll_wait?SIGCHLD 没有被 epoll_wait 捕获?
【发布时间】:2014-06-11 02:38:37
【问题描述】:

我想了解 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)。在我改变它之后,它就像一个魅力。

【问题讨论】:

    标签: c signals fork epoll


    【解决方案1】:

    SIGCHLD 的默认配置将被忽略。阻塞信号不会改变它只是给signalfd 同步处理它的机会。

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

    【讨论】:

    • 我在调用 signalfd 之前添加了以下行,但这也没有帮助。信号(SIGCHLD,dummy_handler);
    • 如果我在 fd 上执行 read() 而不是 epoll_wait,我会得到 SIGCHLD。
    • 你以前用过epoll吗?你明白它只是监视文件描述符活动吗?
    • 我之前没用过epoll,我的理解也一样。我只是想知道为什么孩子离开后我没有收到信号。
    • 如果你按照我上面解释的去做,你就会得到信号。如果您暂时放弃 epoll 并仅对 signal_fd 进行阻塞读取,您将看到它已交付。除此之外,你的问题是如何正确使用 epoll。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-05-31
    • 2012-06-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多