epoll 的一个设计问题

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

内容简介: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 的定义 ,也是这么处理的。


以上所述就是小编给大家介绍的《epoll 的一个设计问题》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

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

两周自制脚本语言

两周自制脚本语言

[日]千叶 滋 / 陈筱烟 / 人民邮电出版社 / 2014-6 / 59.00元

《两周自制脚本语言》是一本优秀的编译原理入门读物。全书穿插了大量轻松风趣的对话,读者可以随书中的人物一起从最简单的语言解释器开始,逐步添加新功能,最终完成一个支持函数、数组、对象等高级功能的语言编译器。本书与众不同的实现方式不仅大幅简化了语言处理器的复杂度,还有助于拓展读者的视野。 《两周自制脚本语言》适合对编译原理及语言处理器设计有兴趣的读者以及正在学习相关课程的大中专院校学生。同时,已经......一起来看看 《两周自制脚本语言》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具