epoll原理是如何实现的?
其实在理解 epoll 之前,得先理解一个事情,那就是进程阻塞切换的 CPU 开销。在高并发的网络 IO 下,性能的最大绊脚石就是 socket 在阻塞后导致的进程上下文切换。关于这个,我进行过实际的测试。大约一次进程上下文切换的开销是 3-5 微秒左右。
可能有的同学会说,3 - 5 微秒的开销看起来还好啊。但是你要知道的是,从我们开发工程师的角度来看,这段时间里 CPU 吭哧吭哧的执行的切换工作对我们来说其实是无用功。
所以 epoll 作为多路复用技术中的代表,和传统的阻塞网络 IO 相比,最大的性能提升就是节约掉了大量的进程上下文切换。 epoll 内部又涉及出了一套复杂的数据结构,包括一棵红黑树和一个就绪链表(以及一个epollwait等待队列)。全部都工作在内核态。通过红黑树,高效地管理海量的连接。在数据到来的时候,不断地将数据 Ready 的socket 放到就绪链表中。
这样应用层和内核态协作的时候就非常的容易了,最少只需要一个进程就可以维护成千上万甚至是百万级别的连接。这个进程的简单地去就绪队列中查看有没有 Ready,需要被处理的 socket。有就拿走处理。只要活儿足够的多,epoll_wait 根本都不会让进程阻塞。用户进程会一直干活,一直干活,直到 epoll_wait 里实在没活儿可干的时候才主动让出 CPU。大量地减少了进程切换次数,这就是 epoll 高效的地方所在!
这是 epoll 工作原理的一张汇总图,供你参考。
最后再说说 epoll 中的红黑树,有的人误以为 epoll 高效的全部因为这棵红黑树,这就有点夸大红黑树的作用了。其实红黑树的作用是仅仅是在管理大量连接的情况下,添加和删除 socket 非常的高效。如果 epoll 管理的 socket 固定的话,在数据收发的事件管理过程中其实红黑树是没有起作用的。内核在socket上收到数据包以后,可以直接找到 epitem(epoll item),并把它插入到就绪队列里,然后等用户进程把事件取走。这个过程中,红黑树的作用并不会得到体现。
Copyright © 广州京杭网络科技有限公司 2005-2025 版权所有 粤ICP备16019765号
广州京杭网络科技有限公司 版权所有