关于 epoll_ctl()

14

在使用 epoll_ctl() 函数时,我发现第三个参数“fd”是除了 epoll 文件描述符“epfd”之外的另一个文件描述符。我看到有这样一个示例:

event.data.fd = sfd; //sfd is a fd for listening
event.events = EPOLLIN | EPOLLET;
s = epoll_ctl (efd, EPOLL_CTL_ADD, sfd, &event);

据我所知,epoll中event.data.fd中的文件描述符与epoll_ctl的第三个参数是相同的,为什么需要将这个描述符传递两次?是否有区别?


1
你可能需要考虑实现并没有为你完成任务。有时候低级别的C系统调用依赖于程序员。事件并不总是必需的,例如在EPOLL_CTL_DEL期间,事件被忽略,但你不能将空指针作为参数传递。 - Ken Cheung
1个回答

20

实际上,您不必设置event.data.fd。它是一个联合体,您可以设置其他成员。当epoll_wait返回时,您将获取与变得有趣的描述符相关联的event.data

typedef union epoll_data {
    void    *ptr;
    int      fd;
    uint32_t u32;
    uint64_t u64;
} epoll_data_t;
这意味着你完全可以自由地选择不在fd中放置任何内容,而是将某些东西放在ptr中(例如)。
总之,epoll_ctl不能依赖于你填写fd的事实,这就是为什么它有一个单独的显式参数。

3
你在调用epoll_ctl时传递的fd是你想要监视事件的文件描述符。而event.data中的fd则完全由你自己使用,系统会忽略它,你可以将其用于任何目的。 - David Schwartz
8
实际上,我看过很多代码将fd放在epoll_data结构中,只是为了将该fd用作在表中索引,该表保存与该套接字相关联的应用程序结构的指针——该结构也包含fd。显然,他们没有意识到可以使用ptr成员而不是fd从而节省查找时间。 - David Schwartz
8
我明白了——在epoll_data中的fd并不是系统使用的,而是供我自己使用的。 - realjin
澄清一下,epoll_ctl(..ADD..)中的ev在你调用epoll_wait()并且有事件发生时会被“吐回来”?@DavidSchwartz 也就是说,你可以在epoll中“存储”指针吗? - awe lotta
只要你在使用完它们后将它们释放,就不会有泄漏的风险。 - David Schwartz
显示剩余3条评论

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