gpt4 book ai didi

linux - EPOLLET 模式下的 Epoll 在从套接字读取之前返回 2 EPOLLIN

转载 作者:太空狗 更新时间:2023-10-29 11:26:40 32 4
gpt4 key购买 nike

epoll 联机帮助页说如果没有完成读取,用 EPOLLET(edge triggered) 注册的 fd 不应该通知两次 EPOLLIN。
因此,在 EPOLLIN 之后,您需要在 epoll_wait 能够针对新数据返回新的 EPOLLIN 之前清空缓冲区。

但是我在使用这种方法时遇到了问题,因为我看到未触及的 fds 有重复的 EPOLLIN 事件。
这是 strace 输出,0x200 是 EPOLLRDHUP,它尚未在我的 glibc 头文件中定义,但已在内核中定义。

30285 epoll_ctl(3, EPOLL_CTL_ADD, 9, {EPOLLIN|EPOLLPRI|EPOLLERR|EPOLLHUP|EPOLLET|0x2000, {u32=9, u64=9}}) = 0
30285 epoll_wait(3, {{EPOLLIN, {u32=9, u64=9}}}, 10, -1) = 1
30285 epoll_wait(3, {{EPOLLIN, {u32=9, u64=9}}}, 10, -1) = 1
30285 epoll_wait(3, <unfinished ...>
30349 epoll_ctl(3, EPOLL_CTL_DEL, 9, NULL) = 0
30306 recv(9, "7u\0\0\10\345\241\312\t\20\f\32\r\10\27\20\2\30\200\10 \31(C0\17\32\r\10\27\20\2\30"..., 20000, 0) = 20000
30349 epoll_ctl(3, EPOLL_CTL_DEL, 9, NULL) = -1 ENOENT (No such file or directory)
30305 recv(9, " \31(C0\17\32\r\10\27\20\2\30\200\10 \31(C0\17\32\r\10\27\20\2\30\200\10 \31("..., 20000, 0) = 10011

因此,在添加 fd 编号 9 之后,我在接收文件描述符之前确实收到了 2 个连续的 EPOLLIN 事件,系统调用跟踪显示了我如何在读取之前删除 fd,但它应该只发生一次,每个事件一个。
所以要么我没有正确阅读联机帮助页,要么现在这里正在工作。

最佳答案

我认为您错过了 epoll 手册页的这一部分:

Since even with the edge-triggered epoll multiple events can be generated upon receipt of multiple chunks of data, the caller has the option to specify the EPOLLONESHOT flag, to tell epoll to disable the associated file descriptor after the receipt of an event with epoll_wait(2). When the EPOLLONESHOT flag is specified, it is the caller's responsibility to rearm the file descriptor using epoll_ctl(2) with EPOLL_CTL_MOD.

也就是说:在您的第一个 read() 发生之前,您有两个数据 block 到达您的接收队列,这意味着您有两个 epoll 事件。看起来 EPOLLONESHOT 是您所追求的,当事件发生时,它将自动从轮询集中删除文件描述符(因此您不需要执行 EPOLL_CTL_DEL)。

关于linux - EPOLLET 模式下的 Epoll 在从套接字读取之前返回 2 EPOLLIN,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2673890/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com