epoll 函数

109 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第7天,点击查看活动详情

epoll 的三个函数

int epoll_create(int size);

  • size: epoll管理的文件描述符的数量(Linux 2.6.8 对 size 没有限制,可以随意,但是 size 必须大于 0)

  • 返回值: 返回一个 epoll 文件描述符,这个 epoll 文件描述符也可以被其他文件描述符所监听管理

int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);        

   

  • epfd: 用于控制某个 epoll 文件描述符事件;

  • op: 控制 epoll 文件描述符事件;op 可以为

    - EPOLL_CTL_ADD: 往 epoll 文件描述符中注册 fd , 利用

    - EPOLL_CTL_MOD: 修改 fd 注册在 epoll 上面的事件

    - EPOLL_CTL_DEL: 把注册的 fd 从epoll 中 删除

  • fd: 要注册在 epoll 上的文件描述符              

  • *event: 事件指针:

    event 相关结构体如下所示:          

    ```

    struct epoll_event {

        uint32_t     events;      /* Epoll events */

        epoll_data_t data;        /* User data variable */

    };

    // 联合体,同一时刻,*ptr,fd u32, u64 仅有一个有效

    typedef union epoll_data {

            void        *ptr;

            int          fd;

            uint32_t     u32;

            uint64_t     u64;

    } epoll_data_t;                  

    ```      

结构体 epoll_event 中的 events 可选项如下:              

  • EPOLLIN: fd 可读

  • EPOLLOUT: fd 可写

  • EPOLLRDHUP: 对端关闭了连接,或者关闭写端

  • EPOLLPRI: 带外数据

  • EPOLLERR: 错误

  • EPOLLHUP: 文件描述符被挂断

  • EPOLLET: 边缘触发;对于读事件 EPOLLIN,只有socket上的数据从无到有,EPOLLIN 才会触发;对于写事件 EPOLLOUT,只有在socket写缓冲区从不可写变为可写,EPOLLOUT 才会触发(刚刚添加事件完成调用epoll_wait时或者缓冲区从满到不满)

  • EPOLLLT:水平触发;对于读事件 EPOLLIN,只要socket上有未读完的数据,EPOLLIN 就会一直触发;对于写事件 EPOLLOUT,只要socket可写(一说指的是 TCP 窗口一直不饱和,我觉得是TCP缓冲区未满时,这一点还需验证),EPOLLOUT 就会一直触发。

int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);

  • epfd: 要检测的 epoll 文件描述符

  • event: 用于回传待处理事件的数组

  • maxevents: 告诉内核 events 数组的大小

  • timeout: 超时事件

    - -1: 永久阻塞

    - 0: 立即返回

    - >0: 等待timeout事件后立即返回