我在看到epoll_wait()
和侦听器套接字之间的以下交互。创建监听套接字事件的顺序是:epoll_wait()在侦听器套接字和虚假故障
- 呼叫
socket()
- 呼叫
bind()
- 电话
fcntl()
,并设置为无阻塞 - 呼叫
epoll_ctl()
与EPOLL_CTL_ADD
和EPOLLET | EPOLLONESHOT | EPOLLIN
- 通话
listen()
后台线程调用epoll_wait()
这个套接字和其他的,如果在步骤4和5之间碰巧这样做,然后收到一个EPOLLHUP
事件监听套接字事件。改变序列:
- 呼叫
socket()
- 呼叫
bind()
- 呼叫
fcntl()
和设置为非阻塞 - 呼叫
listen()
- 呼叫
epoll_ctl()
与EPOLL_CTL_ADD
和EPOLLET | EPOLLONESHOT | EPOLLIN
做出决议THI但现在我发现连接已经生效,但没有收到监听套接字的事件EPOLLIN
。
我的理解可以选择使用电平触发模式,但我希望得到这个边缘触发模式的工作。
对这个问题可能会有什么想法?
谢谢你的回复。我应该澄清,这种虚假故障的情况是与听众端口建立的第一个也是唯一的联系。因此,监听器描述符只能通过EPOLL_CTL_ADD,并且EPOLLONESHOT尚未进入画面。 – user1715664
作为一个实验,我从边缘触发更改为电平触发,仍然看到虚假故障。回顾最近的Linux内核讨论,似乎有一个EPOLLONESHOT错误,可能是负责... http://marc.info/?l=linux-kernel&m=135708457812386&w=2 – user1715664
您是否尝试过第二次连接,看看是否这将套接字唤醒并导致两个成功的accept()?这表明如果连接已经在EPOLL_CTL_ADD点的监听队列中(不太可能,但你永远不知道),边缘触发的通知将不起作用。无论如何你都可以通过调用accept()来解决这个问题(因为它不会阻塞)。但是,一般来说,边缘触发的语义并不总是读/输入端的好主意。 – arayq2