文章插图
作者:后端技术指南针 来自:后端技术指南针
0.概述通过本篇文章将了解到以下内容:
- I/O复用的定义和产生背景
- linux系统的I/O复用工具
- epoll设计的基本构成
- epoll高性能的底层实现
- epoll的ET模式和LT模式
1.复用技术和I/O复用
- 复用的概念
从本质上来说,复用就是为了解决有限资源和过多使用者的不平衡问题,且此技术的理论基础是资源的可释放性 。
- 资源的可释放性
不可释放场景:ICU病房的呼吸机作为有限资源,病人一旦占用且在未脱离危险之前是无法放弃占用的,因此不可能几个情况一样的病人轮流使用 。
可释放场景:对于一些其他资源比如医护人员就可以实现对多个病人的同时监护,理论上不存在一个病人占用医护人员资源不释放的场景 。
- 理解IO复用
复用的含义:那么这些文件描述符FD要复用什么呢?在网络场景中复用的就是任务处理线程,所以简单理解就是多个IO共用1个线程 。
IO复用的可行性:IO请求的基本操作包括read和write,由于网络交互的本质性,必然存在等待,换言之就是整个网络连接中FD的读写是交替出现的,时而可读可写,时而空闲,所以IO复用是可用实现的 。
综上认为,IO复用技术就是协调多个可释放资源的FD交替共享任务处理线程完成通信任务,实现多个fd对应1个任务处理线程 。
现实生活中IO复用就像一只边牧管理几百只绵羊一样:
文章插图
- IO复用的设计原则和产生背景
在网络并发量非常小的原始时期,即使per req per process地处理网络请求也可以满足要求,但是随着网络并发量的提高,原始方式必将阻碍进步,所以就刺激了IO复用机制的实现和推广 。
2.Linux中IO复用工具在Linux中先后出现了select、poll、epoll等,FreeBSD的kqueue也是非常优秀的IO复用工具,kqueue的原理和epoll很类似,本文以Linux环境为例,并且不讨论过多select和poll的实现机制和细节 。
- 开拓者select
文章插图
作为第一个IO复用系统调用,select使用一个宏定义函数按照bitmap原理填充fd,默认大小是1024个,因此对于fd的数值大于1024都可能出现问题,看下官方预警:
文章插图
也就是说当fd的数值大于1024时在将不可控,官方不建议超过1024,但是我们也无法控制fd的绝对数值大小,之前针对这个问题做过一些调研,结论是系统对于fd的分配有自己的策略,会大概率分配到1024以内,对此我并没有充分理解,只是提及一下这个坑 。
存在的问题:
- 可协调fd数量和数值都不超过1024 无法实现高并发
- 使用O(n)复杂度遍历fd数组查看fd的可读写性 效率低
- 涉及大量kernel和用户态拷贝 消耗大
- 每次完成监控需要再次重新传入并且分事件传入 操作冗余
- 继承者epoll
在《Unix网络编程》第三版(2003年)还没有介绍epoll,因为那个时代epoll还没有出现,书中只介绍了select和poll,epoll对select中存在的问题都逐一解决,简单来说epoll的优势包括:
推荐阅读
- 看都不懂的三层架构,到底要怎么理解?
- 谈谈Linux网络协议以及网络栈结构
- 共识算法Raft为什么这么流行,及原理解析
- Windows和Linux通吃,最新远控木马“Dacls”来袭
- 细品Linux系统中文件的三个时间属性
- 活死人意思 活死人的理解
- 开源交换机操作系统
- 如何在 Ubuntu 和其它 Linux 发行版上更新 grub
- Linux发行版之一CentOS的安装与网卡配置
- Linux系统管理命令:openssl