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 的定义 ,也是这么处理的。


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

查看所有标签

猜你喜欢:

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

CSS3专业网页开发指南

CSS3专业网页开发指南

Peter Gasston / 李景媛、吴晓嘉 / 人民邮电出版社 / 2014-3-1 / 45.00元

《CSS3专业网页开发指南》是英国著名Web前端开发工程师Peter Gasston对CSS3高级技术的全面介绍。书中既有CSS3的发展历史、基本语法等入门知识介绍,也涵盖了媒体查询、选择器、伪类与伪元素、网页字体、文本排版、图形处理、动画、布局等CSS3前端开发必不可少的知识,还介绍了CSS3的未来发展方向。全书共分为17章,作者在每一章的讲解中都结合了大量的实例,同时也不忘介绍每一项技术的发展......一起来看看 《CSS3专业网页开发指南》 这本书的介绍吧!

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

在线图片转Base64编码工具

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

在线XML、JSON转换工具