在使用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);
我看到,event.data.fd中的文件描述符与epoll_ctl中的第三个参数相同,为什么需要传递这个描述符两次?有什么区别吗
实际上你没有有设置
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
的事实,这就是为什么它有一个单独的显式参数。
我认为有。
这是我的测试演示。
使用时
ev.data.fd = STDIN_FILENO
在终端中,按 Enter 按钮结束输入并打印“欢迎...”
使用时
ev.data.ptr = stdin
需要按ctrl+d结束输入并打印“欢迎...”
这是否意味着ev.data不仅仅用于记录?
int main()
{
int epfd, nfds;
struct epoll_event ev, events[5];
epfd = epoll_create(1);
//ev.data.fd = STDIN_FILENO;
ev.data.ptr = stdin;
ev.events = EPOLLIN | EPOLLET;
epoll_ctl(epfd, EPOLL_CTL_ADD, STDIN_FILENO, &ev);
for (;;)
{
nfds = epoll_wait(epfd, events, 5, -1);
for (int i = 0; i < nfds; i++)
{
// if (events[i].data.fd == STDIN_FILENO)
if (events[i].data.ptr == stdin)
printf("welcome to epoll's word!\n");
}
}
}