epoll 的一个设计问题

栏目: 后端 · 发布时间: 6年前

内容简介:epoll 的一个设计问题

问题的起因是 skynet 上的一个 issue ,大概是说 socket 线程陷入了无限循环,有个 fd 不断的产生新的消息,由于这条消息既不是 EPOLLIN 也不是 EPOLLOUT ,导致了 socket 线程不断地调用 epoll_wait 占满了 cpu 。

我在自己的机器上暂时无法重现问题,从分析上看,这个制造问题的 fd 是 0 ,也就是 stdin ,猜想和重定向有关系。

skynet 当初并没有处理 EPOLLERR 的情况(在 kqueue 中似乎没有对应的东西),这个我今天的 patch 补上了,不过应该并不能彻底解决问题。

我做了个简单的测试,如果强行 close fd 0 ,而在 close 前不把 fd 0 从 epoll 中移除,的确会造成一个不再存在的 fd (0) 不断地制造 EPOLLIN 消息(和 issue 中提到的不同,不是 EPOLLERR)。而且我也再也没有机会修复它。因为 fd 0 被关闭,所以无法在出现这种情况后从 epoll 移除,也无法读它(内核中的那个文件对象),消息也就不能停止。

我对 epoll 了解的不多,google 了一下,搜到一篇有趣的 blog ,对这个问题有了更多的了解:

Epoll is fundamentally broken

他认为,epoll 的设计失误在于,接口设计上混淆了 "file descriptor" 和 "file description" 。我们在调用接口时,传入的是 file descriptor ,也就是用户空间中那个 fd 数字;但在内核中,引用的却是 file description , 即那个内核对象。如果我们在用户空间 close 了 file descriptor ,就无法再通过 epoll_ctl 去控制它了;但内核里却是按 file description 的生命期去工作的。

一旦出现这种无法消除的消息,唯一的方法只能是把整个 epoll fd 都抛弃掉,重新创建一个。由于这个原因,基于 epoll 的定义实现一个完备的抽象层是非常困难的。

illumos 是一个 OpenSolaris 的分支,它也提供了一套 epoll 的兼容接口,但在这点上,就拒绝按 linux epoll 原本的定义来实现。 https://illumos.org/man/5/epoll

我对比了 freebsd 上 kqueue 的定义 ,也是这么处理的。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

计算理论导引

计算理论导引

[美]Michael Sipser / 张立昂、王捍贫、黄雄 / 机械工业出版社 / 2000-2 / 30.00元

本书由计算理论领域的知名权威Michael Sipser撰写。他以独特的视角,综合地描述了计算机科学理论,并以清新的笔触、生动的语言给出了宽泛的数学理论,而并非拘泥于某些低层次的技术细节。在证明之前,均有“证明思路”,帮助读者理解数学形式下蕴涵的概念。同样,对于算法描述,均以直观的文字,而非伪代码给出,从而将注意力集中于算法本身,而不是某些模型。本书的内容包括三个部分:自动机与语言、可计算性理论和一起来看看 《计算理论导引》 这本书的介绍吧!

MD5 加密
MD5 加密

MD5 加密工具

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试