使用 epoll_wait 和 signalfd 处理信号

Ale*_*llo 6 c sockets signals epoll

我正在echo server使用套接字和系统调用编写自己的程序。我习惯epoll同时与许多不同的客户端一起工作,并且对客户端完成的所有操作都是非阻塞的。当服务器打开并且什么都不做时,它在epoll_wait. 现在我想添加使用信号关闭服务器的可能性。例如,我在 中启动服务器bash terminal,然后按ctrl-c,服务器以某种方式处理SIGINT. 我的计划是使用signalfd. 我使用以下代码创建新的signalfd并将其添加到epoll实例中:

    sigset_t mask;
    sigemptyset(&mask);
    sigaddset(&mask, SIGTERM);
    sigaddset(&mask, SIGINT);
    signal_fd = signalfd(-1, &mask, 0);

    epoll_event event;
    event.data.fd = signal_fd;
    event.events = EPOLLIN;
    epoll_ctl(fd, EPOLL_CTL_ADD, signal_fd, &event);
Run Code Online (Sandbox Code Playgroud)

然后我希望,当我在epoll等待并按下时ctrl-c,事件epoll发生,它唤醒,然后我使用以下代码处理信号:

    if (events[i].data.fd == signal_fd)
    {
        //do something
        exit(0);
    }
Run Code Online (Sandbox Code Playgroud)

虽然实际上服务器只是停止而不处理信号。我做错了什么,解决我的问题的正确方法是什么?如果我没有正确理解信号,应该使用的地方是什么signalfd

Max*_*kin 5

epoll_wait返回-1并且errno == EINTR当通过信号中断。在这种情况下,您需要readsignal_fd.

将信号的信号处理程序设置为SIG_IGN,否则信号可能会终止您的应用程序。

参见man 信号 7

以下接口在被信号处理程序中断后永远不会重新启动,无论使用SA_RESTART; EINTR当被信号处理程序中断时,它们总是因错误而失败:

  • 文件描述符复用接口:epoll_wait(2)、epoll_pwait(2)、poll(2)、ppoll(2)、select(2) 和 pselect(2)。