Linux中select poll和epoll的区别

简介: 在Linux Socket服务器短编程时,为了处理大量客户的连接请求,需要使用非阻塞I/O和复用,select、poll和epoll是Linux API提供的I/O复用方式,自从Linux 2.6中加入了epoll之后,在高性能服务器领域得到广泛的应用,现在比较出名的nginx就是使用epoll来实现I/O复用支持高并发,目前在高并 发的场景下,nginx越来越收到欢迎。

在Linux Socket服务器短编程时,为了处理大量客户的连接请求,需要使用非阻塞I/O和复用,select、poll和epoll是Linux API提供的I/O复用方式,自从Linux 2.6中加入了epoll之后,在高性能服务器领域得到广泛的应用,现在比较出名的nginx就是使用epoll来实现I/O复用支持高并发,目前在高并 发的场景下,nginx越来越收到欢迎。这里有个文章参考。Nginx成为全球Top1000网站最受欢迎的Web服务器

据 w3techs 7月 3 日的统计数据表明,在全球 Top 1000 的网站中,有 34.9% 的网站在使用 Nginx,这使得 Nginx 超越了 Apache,成为了高流量网站最信任的 Web 服务器。下图是统计数据。
这里写图片描述

select:

下面是select的函数接口:

int select (int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);

select 函数监视的文件描述符分3类,分别是writefds、readfds、和exceptfds。调用后select函数会阻塞,直到有描述副就绪(有数据 可读、可写、或者有except),或者超时(timeout指定等待时间,如果立即返回设为null即可),函数返回。当select函数返回后,可以 通过遍历fdset,来找到就绪的描述符。

select目前几乎在所有的平台上支持,其良好跨平台支持也是它的一个优点。select的一 个缺点在于单个进程能够监视的文件描述符的数量存在最大限制,在Linux上一般为1024,可以通过修改宏定义甚至重新编译内核的方式提升这一限制,但 是这样也会造成效率的降低。

poll:

int poll (struct pollfd *fds, unsigned int nfds, int timeout); 

不同与select使用三个位图来表示三个fdset的方式,poll使用一个 pollfd的指针实现。

struct pollfd {
int fd; /* file descriptor */
short events; /* requested events to watch */
short revents; /* returned events witnessed */
};

pollfd结构包含了要监视的event和发生的event,不再使用select“参数-值”传递的方式。同时,pollfd并没有最大数量限制(但是数量过大后性能也是会下降)。 和select函数一样,poll返回后,需要轮询pollfd来获取就绪的描述符。

从上面看,select和poll都需要在返回后,通过遍历文件描述符来获取已经就绪的socket。事实上,同时连接的大量客户端在一时刻可能只有很少的处于就绪状态,因此随着监视的描述符数量的增长,其效率也会线性下降。

epoll:

epoll的接口如下:

int epoll_create(int size);
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
            typedef union epoll_data {
                void *ptr;
                int fd;
                __uint32_t u32;
                __uint64_t u64;
            } epoll_data_t;

            struct epoll_event {
                __uint32_t events;      /* Epoll events */
                epoll_data_t data;      /* User data variable */
            };

int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout);

主要是epoll_create,epoll_ctl和epoll_wait三个函数。epoll_create函数创建epoll文件描述符,参数size并不是限制了epoll所能监听的描述符最大个数,只是对内核初始分配内部数据结构的一个建议。返回是epoll描述符。-1表示创建失败。epoll_ctl 控制对指定描述符fd执行op操作,event是与fd关联的监听事件。op操作有三种:添加EPOLL_CTL_ADD,删除EPOLL_CTL_DEL,修改EPOLL_CTL_MOD。分别添加、删除和修改对fd的监听事件。epoll_wait 等待epfd上的io事件,最多返回maxevents个事件。

在 select/poll中,进程只有在调用一定的方法后,内核才对所有监视的文件描述符进行扫描,而epoll事先通过epoll_ctl()来注册一 个文件描述符,一旦基于某个文件描述符就绪时,内核会采用类似callback的回调机制,迅速激活这个文件描述符,当进程调用epoll_wait() 时便得到通知。

epoll的优点主要是一下几个方面:

  1. 监视的描述符数量不受限制,它所支持的FD上限是最大可以打开文件的数目,这个数字一般远大于2048,举个例子,在1GB内存的机器上大约是10万左 右,具体数目可以cat /proc/sys/fs/file-max察看,一般来说这个数目和系统内存关系很大。select的最大缺点就是进程打开的fd是有数量限制的。这对 于连接数量比较大的服务器来说根本不能满足。虽然也可以选择多进程的解决方案( Apache就是这样实现的),不过虽然linux上面创建进程的代价比较小,但仍旧是不可忽视的,加上进程间数据同步远比不上线程间同步的高效,所以也 不是一种完美的方案。

  2. IO的效率不会随着监视fd的数量的增长而下降。epoll不同于select和poll轮询的方式,而是通过每个fd定义的回调函数来实现的。只有就绪的fd才会执行回调函数。

3.支持电平触发和边沿触发(只告诉进程哪些文件描述符刚刚变为就绪状态,它只说一遍,如果我们没有采取行动,那么它将不会再次告知,这种方式称为边缘触发)两种方式,理论上边缘触发的性能要更高一些,但是代码实现相当复杂。

4.mmap加速内核与用户空间的信息传递。epoll是通过内核于用户空间mmap同一块内存,避免了无畏的内存拷贝。

  • http://www.cnblogs.com/huacw/p/3518461.html
  • http://my.oschina.net/bluesky0leon/blog/132361
  • 目录
    相关文章
    |
    Linux Shell
    在Linux中,umask 和 ulimit有什么区别?
    在Linux中,umask 和 ulimit有什么区别?
    |
    2月前
    |
    存储 Ubuntu 安全
    Linux中Centos和Ubuntu的区别
    CentOS主要面向服务器环境,而Ubuntu适用于服务器和桌面环境。   CentOS提供更精简的安装,而Ubuntu提供更广泛的开箱即用功能。   CentOS遵循RHEL的所有安全实践,而Ubuntu在安全方面采取更积极的方法。
    |
    2月前
    |
    Ubuntu 安全 Unix
    Linux和Ubuntu有什么区别
    综上所述,Linux和Ubuntu之间存在明显的区别。Linux是一种操作系统内核,而Ubuntu是基于Linux内核的发行版本,具有更好的易用性、社区支持和软件仓库。用户可以根据自己的需求选择不同的Linux发行版本,如果需要一个稳定、易于使用的桌面环境,Ubuntu是一个不错的选择。如果需要更加灵活和定制性强的系统,其他Linux发行版本可能更加适合。
    |
    3月前
    |
    安全 Unix Java
    linux中kill -9和kill -15区别
    在 Linux/Unix 系统中,`kill -9` 和 `kill -15` 是终止进程的常用命令,核心区别在于发送的信号类型不同,导致进程终止行为截然不同。`kill -15`(SIGTERM)允许进程进行清理操作后优雅退出,适用于正常关闭;而 `kill -9`(SIGKILL)则强制终止进程,不给予任何清理机会,仅在进程无响应时使用。本文从信号类型、行为、工作原理及使用建议等方面进行详细对比,帮助你更安全、有效地管理进程。
    359 0
    |
    7月前
    |
    Unix Linux 编译器
    windows下和linux下cmake的规则有区别吗
    通过合理使用CMake的条件逻辑和平台特定的配置选项,开发者可以编写更加灵活和健壮的CMake脚本,确保项目在Windows和Linux上的一致性和可移植性。
    350 76
    |
    8月前
    |
    Linux
    linux syscall和int 80的区别
    通过以上内容,希望您能更清晰地理解 `int 0x80` 和 `syscall` 的区别及其在不同系统架构中的应用。
    500 99
    |
    8月前
    |
    缓存 Ubuntu Linux
    Linux中yum、rpm、apt-get、wget的区别,yum、rpm、apt-get常用命令,CentOS、Ubuntu中安装wget
    通过本文,我们详细了解了 `yum`、`rpm`、`apt-get`和 `wget`的区别、常用命令以及在CentOS和Ubuntu中安装 `wget`的方法。`yum`和 `apt-get`是高层次的包管理器,分别用于RPM系和Debian系发行版,能够自动解决依赖问题;而 `rpm`是低层次的包管理工具,适合处理单个包;`wget`则是一个功能强大的下载工具,适用于各种下载任务。在实际使用中,根据系统类型和任务需求选择合适的工具,可以大大提高工作效率和系统管理的便利性。
    835 25
    |
    安全 Linux 应用服务中间件
    在Linux中,包过滤防火墙与代理应用防火墙有什么区别?有哪些相应的产品?
    在Linux中,包过滤防火墙与代理应用防火墙有什么区别?有哪些相应的产品?
    |
    Linux 索引
    在Linux中,符号链接与硬链接有何区别?
    在Linux中,符号链接与硬链接有何区别?
    |
    10月前
    |
    Linux Android开发 开发者
    linux m、mm、mmm函数和make的区别
    通过理解和合理使用这些命令,可以更高效地进行项目构建和管理,特别是在复杂的 Android 开发环境中。
    494 18