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

3
在这个例子中:
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个回答

3
这是一个关于epoll_ctl()的重复问题,即为什么需要两次提供data。原因在于event内的data是一个unionepoll_ctl并不知道您是否实际提供了文件描述符或其他内容。此问题已有解答,请参考最初的回答
typedef union epoll_data {
    void        *ptr;
    int          fd;
    uint32_t     u32;
    uint64_t     u64;
} epoll_data_t;

0

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

其中:

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

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

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

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

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

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

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

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

来源

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

希望这有所帮助!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接