为什么epoll_ctl需要两次filedescriptor?

时间:2019-07-10 15:31:03

标签: file-descriptor epoll

在示例中:

event.events = EPOLLIN;
event.data.fd = fd;

int ret = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, event.data.fd, &event);

我既将文件描述符作为event.data的成员,又作为自身的参数传入。

epoll_ctl需要两次文件描述符是什么?

2 个答案:

答案 0 :(得分:1)

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

位置:

epfd是epoll_create返回的文件描述符,用于标识内核中的epoll实例。

fd是我们要添加到epoll列表/兴趣列表的文件描述符。

op是指要在文件描述符fd上执行的操作。通常,支持三种操作:

  • 使用epoll实例(EPOLL_CTL_ADD)注册fd并获得有关fd发生的事件的通知
  • 从epoll实例中删除/注销fd。这意味着该进程将不再获取有关该文件描述符(EPOLL_CTL_DEL)上事件的任何通知。如果文件描述符已添加到多个epoll实例,则将其关闭会将其从添加了该文件的所有epoll兴趣列表中删除。
  • 修改fd正在监视的事件(EPOLL_CTL_MOD)

event是一个指向名为epoll_event的结构的指针,该结构存储我们实际上要监视fd的事件。

epoll_event结构的第一个字段事件是一个位掩码,用于指示fd正在监视哪些事件。

就像这样,如果fd是一个套接字,我们可能要监视它,以确保新数据到达套接字缓冲区(EPOLLIN)。我们可能还想监视fd的边缘触发的通知,这是通过将EPOLLET与EPOLLIN或运算来完成的。我们可能还想监视fd的已注册事件的发生,但仅监视一次,并停止监视fd的该事件的后续发生。这可以通过对我们要为描述符fd设置的其他标志(EPOLLET,EPOLLIN)与仅一次通知传递EPOLLONESHOT的标志进行“或”运算来实现。可以在手册页中找到所有可能的标志。

epoll_event结构的第二个字段是联合字段。

Source

除了要求提供上下文以外,还添加了一些额外的数据。

希望这会有所帮助!

答案 1 :(得分:1)

这是about epoll_ctl()

的副本

它需要两次的原因是data内的eventunionepoll_ctl不知道您是否确实提供了文件描述符或其他内容。

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