epoll 맨 페이지에 따르면 EPOLLET (에지 트리거 됨)에 등록 된 fd가 읽지 않은 경우 EPOLLIN에 두 번 통보해서는 안됩니다.
그래서 epoll_wait이 새 데이터에 새로운 EPOLLIN을 반환하기 전에 EPOLLIN 후에 버퍼를 비워야합니다.EPOLLET 모드의 Epoll 소켓에서 읽기 전에 2 EPOLLIN을 반환 함
그러나 필자는 수정되지 않은 fds에 대해 중복 된 EPOLLIN 이벤트를보고 있으므로이 방법에 문제가 있습니다.
이것은 strace 출력입니다. 0x200은 아직 내 glibc 헤더에 정의되어 있지 않지만 커널에 정의되어있는 EPOLLRDHUP입니다.
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를 추가 한 후 나는 콜 추적 내가 읽기 전에 FD를 삭제 할 방법을 보여줍니다 파일 기술자를 recving 가진 전에 2 개 연속 EPOLLIN 이벤트를 수신 않지만 그것은 단지 한 번 이벤트에 하나씩 발생한다 .
맨 페이지를 제대로 읽지 않거나 현재 여기서 어떤 작업을하고 있습니다.
좋은 답변입니다. 또 다른 질문이 있습니다 : EPOLLONESHOT이 설정되어 있다면 EPOLLET이 필요합니까? EPOLLONESHOT 이벤트를 수신하는 대부분의 시간에 fd가 IO 작업을 차단할 때까지 IO를 수행 한 다음 이벤트를 다시 설치합니다. – zach