分享

带有边缘触发和单触发的Epoll仅报告一次

 印度阿三17 2019-07-11

我目前正在将一个从accept创建的sockfds添加到epoll实例中,其中包含以下事件:

const int EVENTS = (
    EPOLLET |
    EPOLLIN |
    EPOLLRDHUP |
    EPOLLONESHOT |
    EPOLLERR |
    EPOLLHUP);

触发事件后,我将其传递给处理程序线程,读取然后通过epoll_ctl使用相同的标志重新启用sockfd.但是,我只收到一次EPOLLIN事件.此外,如果我在收到第一个事件后随时杀死客户端,我也不会收到挂断事件.通过阅读手册页,我认为我理解了EdgeTriggered和OneShot的正确方法.

下面是我正在使用的进程的一些伪代码:

const int EVENTS = (
    EPOLLET |
    EPOLLIN |
    EPOLLRDHUP |
    EPOLLONESHOT |
    EPOLLERR |
    EPOLLHUP);

void event_loop()
{
    struct epoll_event event;
    struct epoll_event *events;
    events = calloc(100, sizeof event);
    while (1)
    {
        int x;
        int num_events = epoll_wait(epfd, events, 100, -1);
        for (x = 0; x < num_events; x  )
        {
            another_thread(fd);
        }
    }
}

void another_thread(int fd)
{
    // Read stuff until EAGAIN

    struct epoll_event event;
    event.data.fd = fd;
    event.events = EVENTS;
    epoll_ctl(epfd, EPOLL_CTL_MOD, fd, &event);
}

当我执行EPOLL_CTL_MOD操作时,我没有收到任何错误,但从未收到其他事件的通知.如果我在第一个事件之后重复读取循环,它将读取客户端发送的所有后续数据,因此我知道数据进入并且fd仍然打开并正常工作.

从检查strace开始,线程从clone创建并具有标志CLONE_FILES,因此所有线程共享相同的fd表.

从单独的线程重新启用读取事件的fd的正确方法是什么?

解决方法:

However, I only receive the EPOLLIN event one time. Also, if I kill the client anytime after the first event is received, I do not get hangup events either.

epoll_ctl(2)的手册页说:

EPOLLONESHOT (since Linux 2.6.2)
Sets the one-shot behavior for the associated file descriptor.
This means that after an event is pulled out with
epoll_wait(2) the associated file descriptor is internally
disabled and no other events will be reported by the epoll
interface. The user must call epoll_ctl() with EPOLL_CTL_MOD
to rearm the file descriptor with a new event mask.

在你的情况下,当你得到第一个事件时,epoll会禁用你的sockfd.
当您使用EPOLL_CTL_MOD重新启用sockfd时,它将通知重新注册后内核接收的所有事件.因此,首次通知和重新注册之间的任何事件都将丢失.这可能是没有获取任何挂起事件或数据的原因.

从事件中删除EPOLLONESHOT将更正您的代码,最终您也不需要重新启用sockfd.

由于您使用的是EPOLLET,因此也不存在任何性能问题.

来源:https://www./content-4-317751.html

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多