1.select 和epoll模型区别

1.1.网络IO模型概述

通常来说,网络IO可以抽象成用户态和内核态之间的数据交换。一次网络数据读取操作(read),可以拆分成两个步骤:1)网卡驱动等待数据准备好(内核态)2)将数据从内核空间拷贝到进程空间(用户态)。根据这两个步骤处理方式不一样,我们通常把网络IO划分成阻塞IO和非阻塞IO。

·阻塞IO。用户调用网络IO相关的系统调用时(例如read),如果此时内核网卡还没有读取到网络数据,那么本次系统调用将会一直阻塞,直到对端系统发送的数据到达为止。如果对端一直没有发送数据,则本次调用将永远不会返回。

· 非阻塞IO。当用户调用网络IO相关的系统调用时(例如read),如果此时内核网络还没有收到网络数据,那么本次系统调用将会立即返回,并返回一个EAGAIN的错误码。

在没有IO多路复用技术之前,由于没有一种好的方式来探测网络IO是否可读可写。因此,为了增加系统的并发连接量,一般是借助多线程或多进程的方式来增加系统的并发连接数。但是这种方式有个问题就是系统的并发连接数受限于操作系统的最大线程或进程数,并且随着操作系统的线程或进程数增加,将会引发大量的上下文切换,导致系统的性能急剧下降。为了解决这个问题,操作系统引入了IO多路转接技术(IO multiplexing)。

1.2.  IO多路转接技术

IO多路转接技术其实就是使用select、epoll等操作系统提供的系统调用来检测IO事件的各种机制。通过select、epoll等机制,我们可以很轻松的同时管理大量的网络IO连接,并且获取到处于活跃状态的连接。当其中一个或多个发生网络IO事件时,select、epoll等系统调用就会返回相应的连接,我们就可以对这些连接进行读取或写入操作,从而完成网络数据交互。

1.3.select 工作原理

select函数原型:

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

select各个参数说明:

·  nfds

这个参数的值一般设置为读集合(readfds)、写集合(writefds)以及exceptfds(异常集合)中最大的描述符(fd)+1,当然也可以设置为FD_SETSIZE。FD_SETSIZE是操作系统定义的一个宏,一般是1024。也就是说读写以及异常集合大小的最大值是1024,所以使用select最多只能管理1024个连接。如果大于1024个连接,select将会产生不确定行为。

· readfds

指向可读描述符集的指针,如果我们关心连接的可读事件,需要把连接的描述符设置到读集合中。

·writefds

指向可写描述符集的指针,如果我们关心连接的可写事件,需要把连接的描述符设置到可写集合中。

· exceptfds

指向异常描述符集的指针,如果我们关心连接的是否发生异常,需要把连接的描述符设置到异常描述符集合中。

·timeout

指select愿意等待的时间。

struct timeval {

longtv_sec;      //秒数

longtv_usec;    //微秒数

}

一般来说,分为三种情况:

·timeout为空,select将会永远等待。直到有连接可读、可写或者被信号中断时返回。

·timeout->tv_sec = 0 且 timeout->tv_usec = 0,完全不等待。检测所有指定的描述符后立即返回。这是得到多个描述符的状态而不阻塞select函数的轮询方法。

·timeout->tv_sec != 且 timeout->tv_usec != 0,等待指定的秒数和微秒数。当指定的描述符之一已经准备好,或者超过了指定的时间值,则立即返回。如果超时了,还没有一个描述符准备好,则返回0。

select的工作原理,select通过轮询来检测各个集合中的描述符(fd)的状态,如果描述符的状态发生改变,则会在该集合中设置相应的标记位;如果指定描述符的状态没有发生改变,则将该描述符从对应集合中移除。因此,select的调用复杂度是线性的,即O(n)。举个例子,一个保姆照看一群孩子,如果把孩子是否需要尿尿比作网络IO事件,select的作用就好比这个保姆挨个询问每个孩子:你要尿尿吗?如果孩子回答是,保姆则把孩子拎出来放到另外一个地方。当所有孩子询问完之后,保姆领着这些要尿尿的孩子去上厕所(处理网络IO事件)。

select的限制,前面提到FD_SETSIZE宏,这个宏是操作系统定义的。在linux下面通常是1024,也就是说select最多只能管理1024个描述符。如果大于1024的个描述,select将会产生不可预知的行为。那在没有poll或epoll的情况下,怎样使用select来处理连接数大于1024的情况呢?答案是使用多线程技术,每个线程单独使用一个select进行检测。这样的话,你的系统能够处理的并发连接数等于线程数*1024。早期的apache就是这种技术来支撑海量连接的。

1.4.epoll工作原理

epoll函数原型:

int epoll_create(int size);

intepoll_ctl(int epfd, int op, int fd, struct epoll_event *event);

int epoll_wait(intepfd,  struct epoll_event *events, intmaxevents,  int timeout);

epoll依赖上述三个函数,既可以完成成千上万的并发连接管理。epoll使用方式,1)通过epoll_create建立epoll句柄。2)将描述符所感兴趣的事件通过epoll_ctl添加到epoll句柄中。3)调用epoll_wait返回所有可读写的描述符。

epoll是Linux内核为处理大批量文件描述符而作了改进的epoll,是Linux下多路复用IO接口select/poll的增强版本,它能显著提高程序在大量并发连接中只有少量活跃的情况下的系统CPU利用率。另一点原因就是获取事件的时候,它无须遍历整个被侦听的描述符集,只要遍历那些被内核IO事件异步唤醒而加入Ready队列的描述符集合就行了。epoll除了提供select/poll那种IO事件的水平触发(Level Triggered)外,还提供了边缘触发(Edge Triggered),这就使得用户空间程序有可能缓存IO状态,减少epoll_wait/epoll_pwait的调用,提高应用程序效率。

还是以保姆照看一群孩子为例,在epoll机制下,保姆不再需要挨个的询问每个孩子是否需要尿尿。取而代之的是,每个孩子如果自己需要尿尿的时候,自己主动的站到事先约定好的地方,而保姆的职责就是查看事先约定好的地方是否有孩子。如果有小孩,则领着孩子去上厕所(网络事件处理)。因此,epoll的这种机制,能够高效的处理成千上万的并发连接,而且性能不会随着连接数增加而下降。

1.5.select和epoll对比

综上所述,select和epoll对比如下表所示

select

epoll

性能

随着连接数增加,急剧下降。处理成千上万并发连接数时,性能很差。

随着连接数增加,性能基本上没有下降。处理成千上万并发连接时,性能很好。

连接数

连接数有限制,处理的最大连接数不超过1024。如果要处理超过1024个连接数,则需要修改FD_SETSIZE宏,并重新编译 。

连接数无限制。

内在处理机制

线性轮询

回调callback

开发复杂性

老男孩教育:select和epoll简单区别比喻

select的调用复杂度是线性的,即O(n)。举个例子,一个保姆照看一群孩子,如果把孩子是否需要尿尿比作网络IO事件,select的作用就好比这个保姆挨个询问每个孩子:你要尿尿吗?如果孩子回答是,保姆则把孩子拎出来放到另外一个地方。当所有孩子询问完之后,保姆领着这些要尿尿的孩子去上厕所(处理网络IO事件)。

还是以保姆照看一群孩子为例,在epoll机制下,保姆不再需要挨个的询问每个孩子是否需要尿尿。取而代之的是,每个孩子如果自己需要尿尿的时候,自己主动的站到事先约定好的地方,而保姆的职责就是查看事先约定好的地方是否有孩子。如果有小孩,则领着孩子去上厕所(网络事件处理)。因此,epoll的这种机制,能够高效的处理成千上万的并发连接,而且性能不会随着连接数增加而下降。

本文转自 蓝叶子Sheep 51CTO博客,原文链接:http://blog.51cto.com/dellinger/1952776,如需转载请自行联系原作者

select 和epoll模型区别相关推荐

  1. 【转】select和epoll模型的差异

    http://www.cppblog.com/converse/archive/2008/10/12/63836.html epoll为什么这么快 epoll是多路复用IO(I/O Multiplex ...

  2. IO模型(select, poll, epoll的区别和原理)

    参考<unix网络编程> 参考http://blog.csdn.net/blueboy2000/article/details/4485874 参考http://blog.csdn.net ...

  3. 多路复用select和epoll的区别(转)

    先说下本文框架,先是问题引出,然后概括两个机制的区别和联系,最后介绍每个接口的用法 一.问题引出 联系区别 问题的引出,当需要读两个以上的I/O的时候,如果使用阻塞式的I/O,那么可能长时间的阻塞在一 ...

  4. IO多路复用select,poll epoll以及区别

    看这个一次读懂 Select.Poll.Epoll IO复用技术 文章来简单理解下,如果不是很明白的话,可以参考下面转的知乎上面白话文列子 作者:Leslie 链接:https://www.zhihu ...

  5. linux网络编程系列-select和epoll的区别

    select和epoll属于I/O多路复用模型,用于持续监听多个socket,获取其IO事件. select(轮询) 该模型轮询各socket,不管socket是否活跃,随着socket数的增加,性能 ...

  6. Select和epoll的区别

    当一个节点和多个节点建立连接时,如何高效的处理多个连接的数据,下面具体分析两者的区别. 1. select函数 函数原型:int select(int nfds, fd_set *readfds, f ...

  7. select和epoll的区别详解

    1. 名词解释 1.1 文件描述符fd 文件描述符(File descriptor)是计算机科学中的一个术语,是一个用于表述指向文件的引用的抽象化概念. 文件描述符在形式上是一个非负整数.实际上,它是 ...

  8. [转帖]select提高并发,select和poll、epoll的区别(杂)

    同步IO和异步IO,阻塞IO和非阻塞IO分别是什么,到底有什么区别?不同的人在不同的上下文下给出的答案是不同的.所以先限定一下本文的上下文. https://www.2cto.com/kf/20161 ...

  9. I/O多路复用之select、epoll的实现和区别 ,ET与LT模式

    概念:IO多路复用是指内核一旦发现进程指定的一个或者多个IO条件准备读取,它就通知该进程. select:select系统调用是用来让我们的程序监视多个文件句柄的状态变化. 1.函数原型:intsel ...

最新文章

  1. php 网络请求 get请求和post请求
  2. R语言广义线性模型泊松回归(Poisson Regression)模型
  3. 数据库路由中间件MyCat - 源代码篇(15)
  4. 喜报!在行签约神策数据
  5. 苹果如果无法弹出⏏️
  6. 个人计算机上常用的操作系统,个人计算机常用的输出设备 操作系统的发展史(3)...
  7. wsimport将wsdl生成java 调用时碰到的一个问题Could not initialize Service
  8. SpringBoot - MyBatis-Plus使用详解2(设置实体类对应的表名、字段名 )
  9. 算法高级(6)-共识(Raft)算法
  10. 样条 开源_成年人在开源社区中是什么样的?
  11. 红黑树与平衡二叉树_图解“红黑树”原理,一看就明白!
  12. Pytorch——循环神经网络层、损失函数、优化器
  13. NO Scala sdk module
  14. JSON Web Token从入门到精通
  15. python 构造http请求对象-Request对象
  16. 学java用什么编译器_学习Java用什么编译软件好
  17. vue实现codemirror代码编辑器中的SQL代码格式化功能
  18. Day07 Scanner 类、 Random 类、 ArrayList 类 6.20
  19. 数据挖掘(数据分析)从业指南
  20. linux getcwd 头文件,linux – rsync:getcwd():没有这样的文件或目录(2)

热门文章

  1. AOP联盟通知类型和Spring编写代理半自动
  2. Gun N' Rose 小组分工、项目制品与贡献率计算
  3. 2019.2.4 nfs原理和安装实验
  4. 【Java】二维码生成,QRcode
  5. jquery锚点连接划动滚动条,再也不用a标签name 了
  6. ARM(IMX6U)裸机按键输入实验(BSP+SDK、GPIO输入与输出、按键消抖)
  7. 全国计算机等级考试题库二级C操作题100套(第07套)
  8. 深度相机 物体三维重建_基于深度相机进行室内完整场景三维重建的方法及系统_2017100513665_说明书_专利查询_专利网_钻瓜专利网...
  9. python多线程模块_python 多线程模块参考
  10. 在计算机附近用英语怎么说,附近用英语怎么说