首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >EPOLLET的用例是什么?

EPOLLET的用例是什么?
EN

Stack Overflow用户
提问于 2017-10-08 16:32:51
回答 1查看 5.3K关注 0票数 1

处于边缘触发模式的epoll是一种奇怪的野兽。它要求流程跟踪每个被监控FD的最后响应是什么。它授权流程处理每个报告的事件(否则我们可能会认为FD没有报告任何事情,而实际上,它被边缘触发行为抑制了)。

边缘触发epoll有什么意义?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-10-08 17:50:36

我所知道的EPOLLET的主要用例是使用微线程。

概括地说,用户空间是在微线程之间进行上下文切换(我将称之为“光纤”,因为它更短),这取决于工作的可用性。这也被称为“协作多任务”。

文件描述符的基本处理方法是包装相关的IO函数,如下所示:

代码语言:javascript
运行
复制
ssize_t read(int fd, void *buffer, size_t length) {
  // fd should already be in O_NONBLOCK mode
  while(true) {
    ssize_t result = ::read(fd, buffer, length); // The real read
    if( result!=-1 || (errno!=EAGAIN && errno!=EWOULDBLOCK) )
      return result;

    start_monitoring(fd, READ);
    wait_event();
  }
}

start_monitoring是一个确保监视fd读取可用性的函数。wait_event执行上下文切换,直到调度程序重新唤醒这个光纤,因为fd现在已经准备好了可读取的数据。

epoll实现此功能的通常方法是在start_monitoring中的fd上调用EPOLL_CTL_MOD以添加EPOLLIN侦听,在epoll报告事件后再次添加EPOLLIN侦听以停止侦听EPOLLIN

这意味着拥有可用数据的read将在1个系统调用内完成,但返回EAGAIN的读将至少接受4系统调用(原始read、两个EPOLL_CTL_MOD和成功的最终read )。

请注意,上面没有计算也必须发生的epoll_wait。我不算它,因为我有一个慷慨的假设,即其他光纤也会在同一个系统调用中被唤醒,所以把它的成本完全归因于我们的光纤是不公平的。总之,这种机制需要4+x系统调用,其中x介于0和1之间。

降低成本的一种方法是使用EPOLLONESHOT。这样做可以将fd从自动监控中删除,从而降低3+x的成本。更好,但我们还可以做得更好。

输入EPOLLET。以前的fd状态可以是武装的,也可以是非武装的(也就是说,下一个事件是否会触发epoll)。此外,fd目前(在read的入口点)可能或可能没有准备好数据。四个州。我们把它们摊开。

就绪(无论是否已武装):对read的第一个调用将返回数据。1系统呼叫。这条路不会改变武装状态,准备状态取决于我们是否阅读了所有内容。

还没有准备好(不管是否已准备好):对read的第一个调用返回EAGAIN,从而武装fd。我们在wait_event中睡觉,而不必执行另一个系统调用。一旦我们醒来,我们就处于非武装状态(就像我们刚刚醒来一样)。因此,我们不需要调用epoll_ctl来禁用fd的侦听功能。我们称之为read,它返回数据。我们要么准备好,要么不准备,但没有武器。

总成本: 2+x。

我们将不得不面对一个虚假的唤醒每fd,因为fd开始武装。我们的代码必须处理epoll报告没有光纤监听的fd的情况。在这种情况下,处理只是意味着忽略并继续前进。FD不会再被伪造的报道。

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

https://stackoverflow.com/questions/46633433

复制
相关文章

相似问题

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