`
zhaohaolin
  • 浏览: 1011273 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

在Linux上开发网络服务器的一些相关细节:poll与epoll(转)

阅读更多

随着2.6内核对epoll的完全支持,网络上很多的文章和示例代码都提供了这样一个信息:使用epoll代替传统的poll能给网络服务应用带来性能上 的提升。但大多文章里关于性能提升的原因解释的较少,这里我将试分析一下内核(2.6.21.1)代码中poll与epoll的工作原理,然后再通过一些 测试数据来对比具体效果。

   POLL:

   先说poll,poll或select为大部分Unix/Linux程序员所熟悉,这俩个东西原理类似,性能上也不存在明显差异,但select对所监控 的文件描述符数量有限制,所以这里选用poll做说明。

   poll是一个系统调用,其内核入口函数为sys_poll,sys_poll几乎不做任何处理直接调用do_sys_poll,do_sys_poll 的执行过程可以分为三个部分:

   1,将用户传入的pollfd数组拷贝到内核空间,因为拷贝操作和数组长度相关,时间上这是一个O(n)操作,这一步的代码在do_sys_poll中包 括从函数开始到调用do_poll前的部分。

   2,查询每个文件描述符对应设备的状态,如果该设备尚未就绪,则在该设备的等待队列中加入一项并继续查询下一设备的状态。查询完所有设备后如果没有一个设 备就绪,这时则需要挂起当前进程等待,直到设备就绪或者超时,挂起操作是通过调用schedule_timeout执行的。设备就绪后进程被通知继续运 行,这时再次遍历所有设备,以查找就绪设备。这一步因为两次遍历所有设备,时间复杂度也是O(n),这里面不包括等待时间。相关代码在do_poll函数 中。

   3,将获得的数据传送到用户空间并执行释放内存和剥离等待队列等善后工作,向用户空间拷贝数据与剥离等待队列等操作的的时间复杂度同样是O(n),具体代 码包括do_sys_poll函数中调用do_poll后到结束的部分。

   EPOLL:

   接下来分析epoll,与poll/select不同,epoll不再是一个单独的系统调用,而是由epoll_create/epoll_ctl /epoll_wait三个系统调用组成,后面将会看到这样做的好处。

   先来看sys_epoll_create(epoll_create对应的内核函数),这个函数主要是做一些准备工作,比如创建数据结构,初始化数据并最 终返回一个文件描述符(表示新创建的虚拟epoll文件),这个操作可以认为是一个固定时间的操作。

       epoll是做为一个虚拟文件系统来实现的,这样做至少有以下两个好处:

       1,可以在内核里维护一些信息,这些信息在多次epoll_wait间是保持的,比如所有受监控的文件描述符。

       2, epoll本身也可以被poll/epoll;

   具体epoll的虚拟文件系统的实现和性能分析无关,不再赘述。

   在sys_epoll_create中还能看到一个细节,就是epoll_create的参数size在现阶段是没有意义的,只要大于零就行。

   接着是sys_epoll_ctl(epoll_ctl对应的内核函数),需要明确的是每次调用sys_epoll_ctl只处理一个文件描述符,这里主 要描述当op为EPOLL_CTL_ADD时的执行过程,sys_epoll_ctl做一些安全性检查后进入ep_insert,ep_insert里将 ep_poll_callback做为回掉函数加入设备的等待队列(假定这时设备尚未就绪),由于每次poll_ctl只操作一个文件描述符,因此也可以 认为这是一个O(1)操作

       ep_poll_callback函数很关键,它在所等待的设备就绪后被系统回掉,执行两个操作:

   1,将就绪设备加入就绪队列,这一步避免了像poll那样在设备就绪后再次轮询所有设备找就绪者,降低了时间复杂度,由O(n)到O(1);

   2,唤醒虚拟的epoll文件;

   最后是sys_epoll_wait,这里实际执行操作的是ep_poll函数。该函数等待将进程自身插入虚拟epoll文件的等待队列,直到被唤醒(见 上面ep_poll_callback函数描述),最后执行ep_events_transfer将结果拷贝到用户空间。由于只拷贝就绪设备信息,所以这 里的拷贝是一个O(1)操作。

   还有一个让人关心的问题就是epoll对EPOLLET的处理,即边沿触发的处理,粗略看代码就是把一部分水平触发模式下内核做的工作交给用户来处理,直 觉上不会对性能有太大影响,感兴趣的朋友欢迎讨论。

   POLL/EPOLL对比:

   表面上poll的过程可以看作是由一次epoll_create/若干次epoll_ctl/一次epoll_wait/一次close等系统调用构成, 实际上epoll将poll分成若干部分实现的原因正是因为服务器软件中使用poll的特点(比如Web服务器):

   1,需要同时poll大量文件描述符;

   2,每次poll完成后就绪的文件描述符只占所有被poll的描述符的很少一部分。

   3,前后多次poll调用对文件描述符数组(ufds)的修改只是很小; 

   传统的poll函数相当于每次调用都重起炉灶,从用户空间完整读入ufds,完成后再次完全拷贝到用户空间,另外每次poll都需要对所有设备做至少做一 次加入和删除等待队列操作,这些都是低效的原因。

       epoll将以上情况都细化考虑,不需要每次都完整读入输出ufds,只需使用epoll_ctl调整其中一小部分,不需要每次 epoll_wait都执行一次加入删除等待队列操作,另外改进后的机制使的不必在某个设备就绪后搜索整个设备数组进行查找,这些都能提高效率。另外最明 显的一点,从用户的使用来说,使用epoll不必每次都轮询所有返回结果已找出其中的就绪部分,O(n)变O(1),对性能也提高不少。

   此外这里还发现一点,是不是将epoll_ctl改成一次可以处理多个fd(像semctl那样)会提高些许性能呢?特别是在假设系统调用比较耗时的基础 上。不过关于系统调用的耗时问题还会在以后分析。

   POLL/EPOLL测试数据对比:

   测试的环境:我写了三段代码来分别模拟服务器,活动的客户端,僵死的客户端,服务器运行于一个自编译的标准2.6.11内核系统上,硬件为 PIII933,两个客户端各自运行在另外的PC上,这两台PC比服务器的硬件性能要好,主要是保证能轻易让服务器满载,三台机器间使用一个100M交换 机连接。

   服务器接受并poll所有连接,如果有request到达则回复一个response,然后继续poll。

   活动的客户端(Active Client)模拟若干并发的活动连接,这些连接不间断的发送请求接受回复。

   僵死的客户端(zombie)模拟一些只连接但不发送请求的客户端,其目的只是占用服务器的poll描述符资源。

       测试过程:保持10个并发活动连接,不断的调整僵并发连接数,记录在不同比例下使用poll与epoll的性能差别。僵死并发连接数根据比例分别 是:0,10,20,40,80,160,320,640,1280,2560,5120,10240。

   下图中横轴表示僵死并发连接与活动并发连接之比,纵轴表示完成40000次请求回复所花费的时间,以秒为单位。红色线条表示poll数据,绿色表示 epoll数据。可以看出,poll在所监控的文件描述符数量增加时,其耗时呈线性增长,而epoll则维持了一个平稳的状态,几乎不受描述符个数影响。

   在监控的所有客户端都是活动时,poll的效率会略高于epoll(主要在原点附近,即僵死并发连接为0时,图上不易看出来),究竟epoll实现比 poll复杂,监控少量描述符并非它的长处。
分享到:
评论

相关推荐

    linux epoll服务器

    Linux下的epoll服务器是高性能网络编程中的重要组成部分,它提供了高效、可扩展的I/O多路复用机制。...通过对这些源代码的学习和分析,可以深入理解网络编程的核心概念,提升Linux服务器开发能力。

    基于EPOLL机制的Linux网络服务器设计与实现.pdf

    "基于EPOLL机制的Linux网络服务器设计与实现" 本文介绍了基于EPOLL机制的Linux网络服务器设计与实现。EPOLL是一种高效的IO事件驱动机制,能够提高服务器的性能和可扩展性。在Linux操作系统中,EPOLL机制可以用来...

    基于EPOLL机制的LINUX网络游戏服务器实现方法

    【基于EPOLL机制的LINUX网络游戏服务器实现方法】 在Linux操作系统中,EPOLL机制是一种高效、高性能的I/O处理方式,特别适用于处理大量的并发连接,如网络游戏服务器的需求。EPOLL的引入解决了旧有的多线程同步阻塞...

    linux c epoll服务器windows 客户端通信

    在IT领域,网络编程是不可或缺的一部分,特别是在分布式系统和跨平台通信中。本文将深入探讨如何使用Linux C...在开发过程中,需要充分考虑平台差异,合理利用epoll和Winsock提供的功能,以实现稳定可靠的跨平台通信。

    linux下epoll网络模型介绍

    尽管 epoll 提供了许多优势,但在使用过程中也需要注意一些细节: - **兼容性问题**:虽然 epoll 已经成为了 Linux 内核的标准组件,但在某些旧版本的操作系统或特定配置下可能不支持。因此,在部署时需要确保内核...

    poll和epoll内核源码剖析

    在Linux系统中,I/O模型是处理并发网络编程的关键部分,而`poll`和`epoll`是两种广泛使用的I/O多路复用技术。它们允许一个进程监控多个文件描述符,等待数据就绪,而无需为每个描述符创建单独的线程。这极大地提高了...

    linux 下 通过epoll实现tcp服务器

    在Linux操作系统中,`epoll`是用于I/O多路复用的一种高效机制,尤其适合构建高性能、高并发的网络服务器,例如TCP服务器。本文将详细介绍如何利用`epoll`来实现一个TCP服务器,并结合提供的文件`tcp_epoll_server.c`...

    linux 网络库 C++ epoll

    总的来说,这个网络库为Linux平台上的C++开发者提供了一个轻量级、高效的I/O管理工具,适用于开发高性能的服务器端应用,如WebSocket服务、TCP/UDP通信、实时数据传输等。其关键优势在于epoll的高效性和定时器的灵活...

    linux epoll多线程编程 例子

    《MyLinuxThread.txt》文件可能包含了一个关于如何在Linux上使用epoll和线程池进行编程的实例,这将有助于加深对这一主题的理解。 总结来说,Linux的epoll多线程编程能够有效地提升高并发场景下的系统性能,通过...

    epoll服务器

    总结来说,epoll是Linux环境下实现高性能网络服务器的关键技术,其高效的事件处理机制使得它成为现代服务器开发的首选。通过学习epoll的原理和实现,开发者能够更好地设计和优化大规模并发的网络服务。在`epoll.cpp`...

    Linux下Epoll+线程池的简单Web服务器

    本文将深入探讨如何在Linux环境下使用Epoll和线程池技术构建一个简单的Web服务器。这个Web服务器的实现是基于Linux内核提供的异步I/O模型,Epoll,以及线程池策略,以优化系统资源的使用和提高并发性能。 首先,让...

    Linux环境下Epoll系统调用实现web服务器并发工作

    在Linux操作系统中,为了处理高并发的网络连接,开发者通常会采用I/O多路复用技术,其中Epoll(Event Poll)是Linux提供的一种高效、可扩展的机制。本篇文章将详细探讨如何在Linux环境下利用Epoll系统调用来实现一个...

    牛客网Linux高并发服务器开发.zip

    在IT行业中,Linux系统因其开源、稳定和高效的特点,被广泛应用于服务器开发,尤其是在嵌入式领域。"牛客网Linux高并发服务器开发"这个压缩包文件,显然聚焦于利用Linux进行高性能服务器的设计与实现,这涉及到多个...

    网络io与io多路复用select/poll/epoll 服务器并发代码实现

    在IT领域,网络I/O(Input/Output)是系统与外部设备进行数据交换的关键部分,尤其是在服务器编程中。网络I/O多路复用技术则是一种高效处理并发连接的方法,能够提高服务器性能,允许一个进程同时处理多个客户端请求...

    linux_epoll

    `epoll`在传统的`select`和`poll`基础上进行了改进,提供了更好的性能和可扩展性。本知识讲解将围绕`epoll`的工作原理、如何封装`epoll`以及`epoll_server`和`epoll_client`的实现细节展开。 1. **epoll工作原理** ...

    linux下Epoll模型实例代码

    在Linux操作系统中,Epoll(Event Poll)是用于高并发I/O处理的一种高效机制,尤其适合于网络服务器的开发。Epoll模型相比传统的select、poll等I/O多路复用模型,具有更好的性能和可扩展性。这个"linux下Epoll模型...

    linux epoll代码

    `epoll`在传统的`poll`和`select`基础上进行了优化,解决了它们在处理大量文件描述符时效率低下的问题。本篇文章将深入探讨`epoll`在实现TCP服务器模型中的应用,以及相关的事件驱动编程概念。 一、epoll介绍 1. `...

    EPOLL-linux下select-poll的增强版

    EPOLL 是 Linux 内核提供的 I/O 多路复用技术,它是 Select 和 Poll 的更高效版本,特别是在处理大量并发连接时。EPOLL 提供了一种基于事件的异步 I/O 模型,能够有效地管理和监控大量文件描述符(FDs),显著提高了...

Global site tag (gtag.js) - Google Analytics