天天看点

6种epoll的设计,让你吊打面试官,而且他不能还嘴

select的缺点:

单个进程能够监视的文件描述符的数量存在最大限制,通常是1024,当然可以更改数量,但由于select采用轮询的方式扫描文件描述符,文件描述符数量越多,性能越差;(在linux内核头文件中,

有这样的定义:#define __fd_setsize 1024)

内核 / 用户空间内存拷贝问题,select需要复制大量的句柄数据结构,产生巨大的开销;

select返回的是含有整个句柄的数组,应用程序需要遍历整个数组才能发现哪些句柄发生了事件;

select的触发方式是水平触发,应用程序如果没有完成对一个已经就绪的文件描述符进行io操作,那么之后每次select调用还是会将这些文件描述符通知进程。

相比select模型,poll使用链表保存文件描述符,因此没有了监视文件数量的限制,但其他三个缺点依然存在。

拿select模型为例,假设我们的服务器需要支持100万的并发连接,则在__fd_setsize 为1024的情况下,则我们至少需要开辟1k个进程才能实现100万的并发连接。除了进程间上下文切换的时间消耗外,从内核/用户空间大量的无脑内存拷贝、数组轮询等,是系统难以承受的。因此,基于select模型的服务器程序,要达到10万级别的并发访问,是一个很难完成的任务。

因此,该epoll上场了。

epoll io多路复用模型实现机制

==================

由于epoll的实现机制与select/poll机制完全不同,上面所说的 select的缺点在epoll上不复存在。

设想一下如下场景:有100万个客户端同时与一个服务器进程保持着tcp连接。而每一时刻,通常只有几百上千个tcp连接是活跃的(事实上大部分场景都是这种情况)。如何实现这样的高并发?

在select/poll时代,服务器进程每次都把这100万个连接告诉操作系统(从用户态复制句柄数据结构到内核态),让操作系统内核去查询这些套接字上是否有事件发生,轮询完后,再将句柄数据复制到用户态,让服务器应用程序轮询处理已发生的网络事件,这一过程资源消耗较大,因此,select/poll一般只能处理几千的并发连接。

epoll的设计和实现与select完全不同。epoll通过在linux内核中申请一个简易的文件系统(文件系统一般用什么数据结构实现?b+树)。把原先的select/poll调用分成了3个部分:

1)调用epoll_create()建立一个epoll对象(在epoll文件系统中为这个句柄对象分配资源)

2)调用epoll_ctl向epoll对象中添加这100万个连接的套接字

3)调用epoll_wait收集发生的事件的连接

如此一来,要实现上面说是的场景,只需要在进程启动时建立一个epoll对象,然后在需要的时候向这个epoll对象中添加或者删除连接。同时,epoll_wait的效率也非常高,因为调用epoll_wait时,并没有一股脑的向操作系统复制这100万个连接的句柄数据,内核也不需要去遍历全部的连接。

epoll 很重要,但是 epoll 与 select 的区别是什么呢?epoll 高效的原因是什么?

从网卡接收数据说起

下边是一个典型的计算机结构图,计算机由 cpu、存储器(内存)与网络接口等部件组成,了解 epoll 本质的第一步,要从硬件的角度看计算机怎样接收网络数据。

6种epoll的设计,让你吊打面试官,而且他不能还嘴

计算机结构图(图片来源:linux 内核完全注释之微型计算机组成结构)

下图展示了网卡接收数据的过程:

在 1 阶段,网卡收到网线传来的数据。

经过 2 阶段的硬件电路的传输。

最终 3 阶段将数据写入到内存中的某个地址上。

这个过程涉及到 dma 传输、io 通路选择等硬件有关的知识,但我们只需知道:网卡会把接收到的数据写入内存。

6种epoll的设计,让你吊打面试官,而且他不能还嘴

网卡接收数据的过程

通过硬件传输,网卡接收的数据存放到内存中,操作系统就可以去读取它们。

如何知道接收了数据?

了解 epoll 本质的第二步,要从 cpu 的角度来看数据接收。理解这个问题,要先了解一个概念:中断。

计算机执行程序时,会有优先级的需求。比如,当计算机收到断电信号时,它应立即去保存数据,保存数据的程序具有较高的优先级(电容可以保存少许电量,供 cpu 运行很短的一小段时间)。

一般而言,由硬件产生的信号需要 cpu 立马做出回应,不然数据可能就丢失了,所以它的优先级很高。

cpu 理应中断掉正在执行的程序,去做出响应;当 cpu 完成对硬件的响应后,再重新执行用户程序。

中断的过程如下图,它和函数调用差不多,只不过函数调用是事先定好位置,而中断的位置由“信号”决定。

6种epoll的设计,让你吊打面试官,而且他不能还嘴