【问题标题】:epoll order of events from epoll_wait来自 epoll_wait 的 epoll 事件顺序
【发布时间】:2018-10-28 06:44:45
【问题描述】:

我已经将一个程序从 select 移植到 epoll 以增加我们可以处理的套接字数量。我已经将sockets添加到epoll FD中,可以愉快地读写了。

但是,即使我正在使用关卡触发事件,我也担心可能会出现套接字不足的情况。我担心的情况是当准备好的套接字比epoll_event 结构更多时。我知道下次我打电话给epoll_wait 时,它会给我剩下的,但我想知道我让他们按什么顺序排列,并提醒上次和这次谁没有晋级。

一个例子: 假设我有 10 个套接字连接并添加到 epoll fd。我只有 5 个epoll_event 结构的足够内存。假设在每个epoll_wait 之间的时间里,所有10 个套接字都接收到数据。第一个 epoll_wait 将返回 5 个 epoll_event 结构进行处理,假设它是套接字 1-5。我处理了这 5 个套接字,当我这样做的时候,更多的数据进来了,所有 10 个套接字都有更多的数据要读取。我再次输入epoll_wait 并获得另外5 个epoll_event 结构。

我的问题是,在第二次调用 epoll_wait 时,我将获得哪些 5 个套接字。会不会是套接字 1-5,因为它们首先被添加到 epoll FD 中?或者我会得到套接字 6-10,因为这些事件是在更多数据进入套接字 1-5 之前引发的?

本质上,epoll_wait 是像 FIFO 队列,还是只是简单地扫描套接字的内部列表(从而优先考虑列表中的第一个套接字)。

编辑: 这是Linux内核v4.9.62

【问题讨论】:

  • @jxh epoll 函数是 Linux 特定的。
  • @Someprogrammerdude:其他 Unices 将实现包装 API 以实现兼容性。例如:FreeBSD's Linux binary compatibility feature;甚至 Windows 也有 wepoll
  • 文档在这一点上不清楚。人们希望内核 queues epoll 事件,以便假定的第二个 epoll_wait() 检索文件描述符 6-10 上的事件,但看起来我必须研究内核源才能确定(并且由于它没有记录,它可能会改变)。
  • @jxh 我阅读了您对链接解决方案的回答。如果事件确实保存在链表中,那么 epoll 将像 FIFO 一样工作,我的饥饿问题毕竟不是问题。但是,由于这是对未定义行为的依赖,因此我将保留它以供其他输入,以防它在过去 5 年内发生变化。

标签: c linux sockets epoll


【解决方案1】:

@jxh 关于该行为的观察是正确的,并且该行为由来已久(如果我正确地回忆起多年前与实施者 Davide Libenzi 的电子邮件对话,最初是有意的)。不幸的是,到目前为止还没有记录在案。但是,我已经为即将发布的手册页修复了这个问题,epoll_wait(2) 将携带文本:

如果超过 maxevents 个文件描述符准备就绪时 epoll_wait() 被调用,然后连续的epoll_wait() 调用将 循环通过准备好的文件描述符集。这 行为有助于避免进程失败的饥饿情况 注意到额外的文件描述符已经准备好了,因为它 专注于一组已知的文件描述符 准备好了。

【讨论】:

  • 我看到您对手册页的提交澄清了这种行为,我会将您的回复标记为答案,因为它是最权威的。我赞扬您为维护手册页所做的努力,而不是我希望我的敌人完成的任务。
【解决方案2】:

仔细阅读epoll 的源文件,可以看到就绪事件保存在一个链表中。事件从列表的头部移除并添加到列表的末尾。

基于此,答案是描述符顺序基于它们准备就绪的顺序。

【讨论】:

  • 我从一个相关问题中复制了我的答案。这个答案是社区 wiki 的。
  • 美中不足似乎是 “我只有足够的内存用于 5 个 epoll_event 结构。” 问题的一部分——这就是我所在的位置有点失落。这与“内存不足”的情况有关。我假设程序在用户空间中运行,所以如果 epoll 代码在内核空间的链表中排队事件,那么列表可能会在事件发生时继续添加事件。但是,如果列表保存在用户空间中并且引发了内存不足的情况,我看不到一些错误情况是如何没有引发的,从而导致它们没有被保存。我想错了吗?
  • @DavidC.Rankin:我认为这是一个假设的限制,以说明他试图提出的问题。假设epoll接口的内核实现只受系统FD限制,而用户空间可以任意限制(比如通过ulimitsysconfig),那么他只想知道会发生什么当他清除上一次调用epoll_wait的事件后重新发出epoll_wait
  • @DavidC.Rankin: Err... 进程的 FD 限制将在内核中强制执行。我不知何故忘记了新的套接字实际上堆积在接受套接字上,直到在调用 accept 时创建了正确的 FD。
  • 谢谢。我选择了 epoll 代码——但我需要很长时间才能准确地理解它是如何工作的。它只是让我觉得这是一个非常有趣的问题。
猜你喜欢
  • 2016-01-27
  • 2021-11-20
  • 2011-02-27
  • 2014-09-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多