假设我的进程使用epoll和Edge Trigger,以及以下内容 场景发生:
epoll_wait()会立即返回吗?或者等到下一个数据进入?
答案 0 :(得分:1)
会立即返回。
不幸的是,边缘触发模式描述得不是很好(不是以任何方式,所以正常人无法理解它并且无论如何都不能做出错误的假设)。
它的作用是,当描述符的状态变为“就绪”(或者,无论你等待什么)时,它只生成一个事件,这意味着epoll_wait()
将返回一次。然而,这不是故事的结局。
一旦状态转换为“未准备好”并返回,它就会生成下一个事件。这一点非常重要。单独进入的数据通常不够(虽然根据文档可能,并且传入数据可能生成多个事件。 。bleh)。
对于像插座或管道之类的东西,细微之处并不重要,因为无论如何你都要读取数据。这也是显而易见的,如果你考虑一下,它也很有意义。
如果描述符为false
,则强调将{1}}翻转回true
非常重要。假设您只需要唤醒服务员就可以发出eventfd的信号(并且它不会多次唤醒等待的线程,这很好)。当然,这就是它必须如何,而不是任何不同。没有人关心你发布的价值,呵呵......它只能存储一个被覆盖的值,而且我也不在乎阅读它。
嗯,这是不如何运作,因为我发现了困难。唤醒一次后,您需要实际读取描述符,以便在再次等待之前将状态翻转为“未就绪”。否则,出乎意料的是,自你上次醒来以来另一件事发生的事实是无关紧要的 再说一次,如果你考虑一下,这甚至是有道理的。它可能不是你所期望的。
编写程序的方式,它将按预期工作。但请注意,只给出一个描述符,阻止它会更有效。
答案 1 :(得分:1)
这实际上是在epoll(7)
manual page中解答的(在“水平触发和边缘触发”一节中)。
手册中说的是它应该可以正常工作,因为EPOLLET
事件是由更改触发的,并且更改发生在您的步骤4中。
手册页甚至说使用EPOLLET
解决问题的方法是
带有非阻塞文件描述符;以及
- 醇>
仅在
read(2)
或write(2)
返回EAGAIN
之后等待活动。
您已经做过的事情(即使您使用等效的EWOULDBLOCK
代替EAGAIN
)。
简而言之:当您迭代回到第1步时,epoll_wait
应立即返回。