在示例中:
event.events = EPOLLIN;
event.data.fd = fd;
int ret = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, event.data.fd, &event);
我既将文件描述符作为event.data
的成员,又作为自身的参数传入。
epoll_ctl
需要两次文件描述符是什么?
答案 0 :(得分:1)
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event)
位置:
epfd
是epoll_create返回的文件描述符,用于标识内核中的epoll实例。
fd
是我们要添加到epoll列表/兴趣列表的文件描述符。
op
是指要在文件描述符fd上执行的操作。通常,支持三种操作:
event
是一个指向名为epoll_event的结构的指针,该结构存储我们实际上要监视fd的事件。
epoll_event
结构的第一个字段事件是一个位掩码,用于指示fd正在监视哪些事件。
就像这样,如果fd是一个套接字,我们可能要监视它,以确保新数据到达套接字缓冲区(EPOLLIN)。我们可能还想监视fd的边缘触发的通知,这是通过将EPOLLET与EPOLLIN或运算来完成的。我们可能还想监视fd的已注册事件的发生,但仅监视一次,并停止监视fd的该事件的后续发生。这可以通过对我们要为描述符fd设置的其他标志(EPOLLET,EPOLLIN)与仅一次通知传递EPOLLONESHOT的标志进行“或”运算来实现。可以在手册页中找到所有可能的标志。
epoll_event结构的第二个字段是联合字段。
除了要求提供上下文以外,还添加了一些额外的数据。
希望这会有所帮助!
答案 1 :(得分:1)
它需要两次的原因是data
内的event
是union
。 epoll_ctl
不知道您是否确实提供了文件描述符或其他内容。
typedef union epoll_data {
void *ptr;
int fd;
uint32_t u32;
uint64_t u64;
} epoll_data_t;