首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >侦听器套接字上的epoll_wait()和虚假故障

侦听器套接字上的epoll_wait()和虚假故障
EN

Stack Overflow用户
提问于 2013-01-08 18:08:51
回答 1查看 1.4K关注 0票数 2

我看到了epoll_wait()和侦听器套接字之间的以下交互。创建侦听器套接字的事件序列是:

  1. 调用socket()
  2. 调用bind()
  3. 调用fcntl()并设置为非阻塞
  4. epoll_ctl()EPOLL_CTL_ADD调用EPOLLET | EPOLLONESHOT | EPOLLIN
  5. 调用listen()

有后台线程调用此套接字和其他套接字的epoll_wait(),如果在步骤4至步骤5之间恰好这样做,则会收到侦听器套接字的EPOLLHUP事件。将顺序更改为:

  1. 调用socket()
  2. 调用bind()
  3. 调用fcntl()并设置为非阻塞
  4. 调用listen()
  5. epoll_ctl()EPOLL_CTL_ADD调用EPOLLET | EPOLLONESHOT | EPOLLIN

解决了这个问题,但是现在我看到了虚假的失败,在这里连接是建立的,但是侦听器套接字没有接收到EPOLLIN事件。

我知道一个人可以选择使用水平触发模式,但我想让这个工作边缘触发模式。

对这个问题有什么想法吗?

EN

回答 1

Stack Overflow用户

发布于 2013-01-08 18:35:02

EPOLLONESHOT的语义是,一旦epoll_wait()为某个描述符提取了一个通知,您就必须用EPOLL_CTL_MOD调用epoll_ctl()来重新启用该描述符上的通知。因此,您可能因为EPOLLONESHOT禁用了被动/侦听套接字上的通知而缺少连接。(通常,除特殊情况外,不应使用EPOLLONESHOT;自动添加到代码中并不是样板或巫毒。)

此外,对于非阻塞边缘触发的语义,在通知侦听套接字已准备好输入时,需要在循环中调用accept(),直到报告EAGAIN错误为止。只调用accept()一次就可以将其他连接留在队列中,而且,在向队列中添加全新连接之前,不会发生另一个边缘触发的EPOLLIN事件。(也就是说,假设没有指定EPOLLONESHOT,或者在下次调用epoll_wait()之前每次都重新启用描述符。)

增编消除EPOLLONESHOT无疑值得一试。你到底为什么需要它?

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14221339

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档