epoll_ctl 函数(译)

http://man7.org/linux/man-pages/man2/epoll_ctl.2.html

梗概:

 #include <sys/epoll.h>
 int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);

描述
该系统调用 执行epoll实例epfd上的操作,它需要具体执行的操作op以及被op执行的目标文件描述符 fd.

有效的op 参数如下:

    • EPOLL_CTL_ADD

注册的文件描述符df在 epfd 上,把event事件和fd绑定在一起。

    • EPOLL_CTL_MOD

修改注册到fd参数上的监听事件

    • EPOLL_CTL_DEL

从epfd中删除fd,这里event参数可以没有,用NULL
参数 event 描述的是fd对象的变化,epoll_event 结构体定义如下

 typedef union epoll_data {
               void        *ptr;
               int          fd;
               uint32_t     u32;
               uint64_t     u64;
           } epoll_data_t;

           struct epoll_event {
               uint32_t     events;      /* Epoll events */
               epoll_data_t data;        /* User data variable */
           };

events 是一个使用如下参数的位集合。

    • EPOLLIN

关联的文件可以执行read 操作

    • EPOLLOUT

关联的文件可以进行写操作

    • EPOLLRDHUP (Linux 2.6.17之后有)

socket刘关闭连接或则是关闭写半连接()

    • EPOLLPRI

有紧急的数据需要去读

    • EPOLLERR

有错误在关联的文件上发生,epoll_wait 总是等这种事件发生,并不需要在events中设置。此时接口可写。

    • EPOLLHUP

关联的文件描述符挂断了。epoll_wait 会处理这种情况,不需要特意在events中设置,注意,当从信道或者socket流中读取的时候,这个时间紧紧只是说,连接被关闭了,从该管道中读取,当全部数据读取完的时候,才会返回0,即文件结束。此时接口可写。

    • EPOLLET

设置关联的文件描述符上的边界触发信号,epoll默认的是水平触发。

    • EPOLLONESHOT(linux 2.6.2之后的版本)

为关联的文件描述符设置一次监听,也就是说,触发了事件之后,文件描述符就从epoll_wait的等待队列中剔除,用户必须再次调用epoll_ctl,使用EPOLL_CTL_MOD 才可以重新事件掩码。

    • EPOLLWAKEUP(Linux 3.5之后)

如果EPOLLONESHOT和EPOLLET被清除,并且进程有被CAP_BLOCK_SUSPEND ,确保系统不会在处理或者 等待中 进入挂起或者休眠的状态,在第一次在该文件描述符上调用了epoll_wait,第二次调用之前,在关闭文件描述之前,在通过EPOLL_CTL_DEL 移除事件之前,或者是通过EPOLL_CTL_MOD 移除EPOLLWAKEUP 之前, 在该事件会被一直认为在处理中。

返回值

成功执行后,epoll_ctl 返回0,发生错误的时候,epoll_ctl返回-1,并且errno 会被设置成合适的值。

可能的错误情况
  • EBADF epfd 或者df 不是正确的文件描述符。
  • EEXIST op 是EPOLL_CTL_ADD,并且fd已经被注册在该epoll实例 epfd上面了。
  • EINVAL epfd 不是 epoll文件描述或者fd和epfd一样,或者请求的op并不支持该接口。
  • ENOENT op 是EPOLL_CTL_MOD 或者是EPOLL_CTL_DEL,并且df 并没有被注册到该epoll 实例上。
  • ENOSPC 在EPOLL_CTL_ADD的时候被 /proc/sys/fs/epoll/max_user_watches 强制限制
  • EPERM fd并不支持epoll,这种错误可能发生在一个fd是一个正常文件或者是一个目录的时候。

版本

epoll_ctl 是在linux 2.6之后加进去的。

Leave a comment

Your email address will not be published.

*