Epoll学习笔记

Epoll性能特点

SelectPollEpollKqueue几种I/O多路复用做测试(限制100个活动连接,并且每一个连接会有1000次写入)

下图是 libevent(一个知名的异步事件处理软件库)对这几个 I/O 多路复用技术做的性能测试。

在这里插入图片描述

实验结果

fd数量<1000时,这几种I/O复用的性能相互接近,当随着fd的数量越来越多,EPOLLKqueue的相应时间相接近,并且远小SelectPoll的响应时间

实验分析

通过实验结果,可以看出Epoll在面对大量连接时性能表现优异。

但是,不是任何时候,Epoll面对大量连接时都能够有如此表现,上述实验有个很重要的限制条件,100 Active Connections,也就是说,假设Epoll应对大量fd(15000个),此时其中只有100个活跃连接,Epoll才会明显优于其他I/O复用。

如果当活跃连接也为15000个时,Epoll将会和Select以及Poll性能相近。

在谈Epoll原理之前,先看几个问题(无需知道为什么),并且通过下面的原理解读来理解这些问题


Q: 为什么会出现I/O多路复用

A: 为了减少进程上下文切换带来的开销。


Q: 是Linux已发行就有Epoll了吗?

A:

I/O多路复用是一种技术,而SelectPollEpoll是实现了该技术的框架。

框架的api发布的时间线:

  • 1983,socket 发布在 Unix(4.2 BSD)
  • 1983,select 发布在 Unix(4.2 BSD)
  • 1994,Linux的1.0,已经支持socket和select
  • 1997,poll 发布在 Linux 2.1.23
  • 2002,epoll发布在 Linux 2.5.44

这些框架的出现是以不断改进的方式向前推进的:Select->Poll->EpollPoll是在Select的基础上改进,EpollPoll的基础上改进,可以这么说,Epoll是在I/O多路复用框架不断发展的结果。


Q: Epoll解决了什么问题?

A: Epoll优化了内核监视进程监视fd的进程)的交互


1 Epoll原理

1.1 阻塞

Epoll为什么是阻塞的,这是因为内核收发网络数据的底层机制导致的,并且,阻塞才是高效的方式。

接收网络数据的过程:

在这里插入图片描述

网卡接收数据依赖发送方和传输路径,延迟是毫秒(ms)级别的,相对于用户进程处理数据的纳秒级来说相对很慢,所以用户态的用户进程在等待数据的过程中CPU空闲,此时通过阻塞该进程来让出CPU资源(阻塞不占用CPU资源),提高CPU的利用率。


1.2 阻塞恢复

问题来了,当用户进程阻塞等待数据,数据接受完毕后怎么办

Sokcet结构体包含两个数据:进程ID(调用send,read,connect的进程)and端口号

当数据从网卡到内核时,内核通过端口号来确定对应的Sokcet

当数据从内核到用户进程时,内核通过进程ID来确定目标进程,然后修改目标进程的状态,从阻塞状态变为可执行状态,最后通过OS的进程调度,该进程得以从可执行状态变为运行状态,最终用户的数据得以处理完毕


1.3 过程优化

进程接收数据的过程存在两处可能造成频繁上下文切换产生大量不必要开销

1.如果频繁接收到Packet,那么网卡会频繁发出IRQ,此时,CPU不一定在内核态,有可能在用户态,因此可能会造成大量的内核态与用户态之间频繁的切换

2.one socket - one proccess,当一个Sokcet处理完,就一定伴随着进程间调度,存在进程间的上下文切换

解决办法:缓冲区的思想

解决问题1:通过网卡驱动中的一种机制NAPI机制,这里有兴趣的小伙伴可以自己去了解了解,这里不展开赘述,我直接总结一下:就是批量收发数据减少内核态与用户态的切换次数

解决问题2:你肯定已经想到了,解决进程间调度的办法也是批量收发数据呗,问题就在于怎样去操作。网卡可以通过NAPI机制,内核可以通过大名鼎鼎的I/O多路复用技术来优化。就是n Socket - one proccess,说白了就是Socket 复用一个进程中。


1.4 EPOLL存储fd数据结构

1.由两个结构体组成,总集就绪队列

2.数据结构:1.红黑树存储总集 fd,2链表存储就绪fd


1.5 Epoll与Select、Poll之间的比较

1.提高了总集大小:fd数量上限是系统最大可以打开的文件数目(主机内存限制)

2.采用通知机制:每个fd上有callback函数,只有活跃的Socket才会调用callback函数

3. 提高了活跃Socket的查找效率:由于通过epoll_wait直接获取到的就是活跃Socket,所以用户进程查找时间复杂度为O(活跃连接数量*logn),而Poll和Select需要线性查找时间复杂度O(活跃连接数量*n)

若当活跃连接数量远小于总量n时,Epoll时间复杂度可看作O(logn)Poll和Select时间复杂度可看作O(n),此时Epoll性能优!

若当活跃连接与n相近时,则Epoll时间复杂度为O(nlogn)Poll和Select时间复杂度可看作O(n^2),性能相差不大,甚至在某些业务场景Epoll性能还不如Poll和Select,所以Epoll并不是所谓的万金油,要具体问题具体分析

3.数据处理问题:内核和用户通过mmap共享内存,避免内存拷贝(据说不同的linux版本,Epoll不用mmap,这个以后通过实践考证)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值