网络编程实战
盛延敏
前大众点评云平台首席架构师
44207 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 40 讲
网络编程实战
15
15
1.0x
00:00/00:00
登录|注册

23 | Linux利器:epoll的前世今生

epoll_create1
epoll_create
实验
代码解析
epoll_wait
epoll_ctl
epoll_create
历史
edge-triggered VS level-triggered
例子
使用方法
性能优势
I/O多路复用
非阻塞I/O
思考题
总结
epoll
性能篇的前三讲
Linux利器:epoll的前世今生

该思维导图由 AI 生成,仅供参考

你好,我是盛延敏,这里是网络编程实战第 23 讲,欢迎回来。
性能篇的前三讲,非阻塞 I/O 加上 I/O 多路复用,已经渐渐帮助我们在高性能网络编程这个领域搭建了初步的基石。但是,离最终的目标还差那么一点,如果说 I/O 多路复用帮我们打开了高性能网络编程的窗口,那么今天的主题——epoll,将为我们增添足够的动力。
这里有放置了一张图,这张图来自 The Linux Programming Interface(No Starch Press)。这张图直观地为我们展示了 select、poll、epoll 几种不同的 I/O 复用技术在面对不同文件描述符大小时的表现差异。
从图中可以明显地看到,epoll 的性能是最好的,即使在多达 10000 个文件描述的情况下,其性能的下降和有 10 个文件描述符的情况相比,差别也不是很大。而随着文件描述符的增大,常规的 select 和 poll 方法性能逐渐变得很差。
那么,epoll 究竟使用了什么样的“魔法”,取得了如此令人惊讶的效果呢?接下来,我们就来一起分析一下。

epoll 的用法

在分析对比 epoll、poll 和 select 几种技术之前,我们先看一下怎么使用 epoll 来完成一个服务器程序,具体的原理我将在 29 讲中进行讲解。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

Linux网络编程中的高性能I/O多路复用技术——epoll在提高系统性能方面具有显著优势。文章通过对比select、poll和epoll的性能表现,详细介绍了epoll的用法,包括epoll_create、epoll_ctl和epoll_wait三个API的具体操作步骤。作者还给出了基于epoll的服务器程序示例,展示了如何使用epoll实现高性能的网络编程。此外,文章还介绍了epoll的两种模式:条件触发和边缘触发,以及epoll的历史和与其他系统的比较。总的来说,本文为读者提供了深入了解和应用epoll的基础知识,对于从事Linux网络编程或对高性能I/O多路复用技术感兴趣的读者来说,是一篇值得阅读的技术文章。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《网络编程实战》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(51)

  • 最新
  • 精选
  • 传说中的成大大
    我回想和对了poll和epoll的代码 觉得效率问题主要出现在 epoll返回的是有事件发生的数组,而poll返回的是准备好的个数,每次poll函数返回都要遍历注册的描述符结合数组 尤其是数量越大遍历次数就越多 我觉得性能差异在这里 抛开阻塞和阻塞i/o层面

    作者回复: 这是一个很重要的点,恭喜你悟到了 :)

    2019-10-08
    5
    67
  • yusuf
    https://github.com/linuxxiaoyu/block 执行后都会重复打印”need read socket_fd“和“poll need to read”,所以select和poll应该都是条件触发

    作者回复: 就喜欢你这样努力完成作业,实际写代码的样子。赞赞赞。

    2019-10-21
    21
  • moob
    边缘触发的情况, 如果epoll_wait时提供的events数组太小,那么会错过事件?

    作者回复: 如果你读了后面答疑部分的源码就会明白,答案是否定的。如果你设置一个很小的events数组,会影响事件的时效性,也就是说,可能10秒前的一个I/O事件,现在你才收到,但是不会错过事件,其原因是事件总在内核中记录着。你不收,内核里也有;你收的快一点,时效性就越好,表现出对用户的体验就越好。

    2019-10-15
    20
  • yusuf
    之前对epoll01.c中第66行while(1)很困惑,不明白是从哪里跳出这个循环的。后来通过gdb调试分析,发现在55行把socket_fd设置为了非阻塞,然后在68行调用read时,socket_fd没有数据可读会直接返回-1(errno = EAGAIN),从而在73行通过break跳出了while(1)循环。希望对同样有此困惑的同学有所帮助。

    作者回复: gdb都用上了,牛~

    2019-10-21
    4
    15
  • 空想家
    LT + non-blocking 和 ET + non-blocking 有什么区别吗?性能谁更好一点? epoll 的惊群问题会讲吗?

    作者回复: LT和ET的区别在文稿里已经给出了。 我理解的惊群问题是当一个网络套接字上有事件发生时,多个线程或者进程会感知,从而引发一群线程干活。 我认为设计良好的程序应该避免这样的问题,比如一个套接字只被一个线程所管理。我们后面的框架设计也是遵循了这个原则。

    2019-09-30
    2
    11
  • 向东
    为何在水平触发的epoll03,当tcpclient都退出了,还说有数据可读呢,get event on socket fd ==5,二是请问为何每次都从五开始呢,前面0-5分别是谁占用了呢,谢谢。

    作者回复: 因为这部分数据没有被处理掉,而这个正是条件触发的精髓。 至于描述字,我是这么理解的,0,1,2分别被stdin, stdout和stderr所用,3被监听套接字所用,本地连接的客户端描述字是4,那么本地已连接套接字就是5了。

    2019-10-03
    6
  • herongwei
    老师,您好,在总结里:“避免了用户态 - 内核态频繁的数据拷贝”这句话是什么意思的呢?文稿中好像没有提到 epoll 的数据拷贝?频繁指的是什么呢?另外,对比之前的 ,select,poll,epoll 三者在数据拷贝之间的区别又有什么不同呢?希望老师回答一下,谢谢!

    作者回复: 在后面的章节里对select、poll、epoll这几个技术进行了不同程度的比较,你可以接着往下读。

    2019-10-24
    3
    5
  • нáпの゛
    老师,边沿触发的时候,如果没有把数据全部读完,剩余的未读数据后续是什么情况。在缓存区中会影响socket后续的读写操作吗,比如这会请求其他资源,触发另一个读时间,会不会读到前面未读的数据?还是说不影响,内核在新的读操作之后会清理掉?

    作者回复: 当然会读到之前的数据,因为TCP是流式数据,像水流一样,连绵不绝,之前的数据不会被扔掉。

    2020-09-02
    4
  • ray
    老师您好, 想跟您请教什么时候会触发EPOLLOUT事件,我们的课程范例好像都只有EPOLLIN事件。 当读事件触发后,为什么不用为fd设置EPOLLOUT事件,就可以直接将资料写回fd,这样我们要怎么知道一个fd是否可写呢? 谢谢老师的解答!

    作者回复: 非常好的问题。 实际上,确实需要通过注册EPOLLOUT事件,让内核告诉我们可以往某个fd上写数据,课程只是没有展现这部分的能力而已,而在lib/epoll_dispatcher.c中是会注册EPOLLOUT事件的。

    2020-04-27
    4
  • Steiner
    请问如果我用epoll_ctl显式更改event事件,那么epoll_wait会不会检测到,并装载到events数组中?

    作者回复: 当然会,自动更新,动态检测,这就是NB的地方啊。

    2019-10-23
    4
收起评论
显示
设置
留言
51
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部