在深入理解select、poll和epoll之间的区别之前,首先要了解什么是IO多路复用模型。

IO多路复用

简单来说,IO多路复用是指内核一旦发现进程指定的一个或者多个IO条件准备就绪,它就通知该进程去进行IO操作。

详细的描述可以参考IO模型。select、poll和epoll都是提供I/O多路复用的解决方案。

select

  • 函数
int select(int maxfdp, fd_set *readset, fd_set *writeset,
fd_set *exceptset, struct timeval *timeout);
  • 基本原理:select 函数监视的文件描述符分3类,分别是writefdsreadfds、和exceptfds。调用select时会被阻塞,直到有fd就绪(读、写、或者异常),或者超时(timeout指定等待时间,如果立即返回设为null即可)函数返回一个大于0的值,然后通过遍历文件描述符集合fd_set,来找到就绪的描述符
  • 说明maxfdp是一个整数值,是指集合中所有文件描述符的范围,即所有文件描述符的最大值加1。fd_set是以位图的形式来存储这些文件描述符。maxfdp也就是定义了位图中有效地位的个数
  • 时间复杂度O(n)n为文件描述符集合fd_set的大小
  • 文件描述符最大限制1024

poll

  • 函数
int poll ( struct pollfd * fds, unsigned int nfds, int timeout);
  • 基本原理:和select 函数很相似,定义了一个struct pollfd结构类型的数组,用于存放需要检测其状态的所有文件描述符。调用poll函数之后,系统不会清空这个数组。特别是对于文件描述符比较多的情况下,在一定程度上可以提高处理的效率。这一点与select()函数不同,调用select()函数之后,select()函数会清空它所检测的文件描述符集合,导致每次调用select()之前都必须把文件描述符重新加入到待检测的集合中。因此,select()函数适合于只检测一个文件描述符的情况,而poll()函数适合于大量文件描述符的情况
  • 时间复杂度O(n)n为文件描述符集合的大小
  • 文件描述符最大限制:无限制,fds是一个链表

epoll

  • 函数
// 建立一个epoll对象,参数size是内核保证能够正确处理的最大句柄数
int epoll_create(int size);
// 操作上面建立的epoll
// 例如,将刚建立的socket加入到epoll中让其监控,或者
// 把 epoll正在监控的某个socket句并移出epoll
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
// 在指定的timeout时间内,当所有句柄中有事件发生时,就返回给用户态的进程
int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout);
  • 基本原理:将所有的文件描述符fd_set存储在共享内存(用户空间和内核空间都可以直接访问)。调用epoll_create函数创建epoll对象,并以红黑树的结构存储在内核空间,epoll_ctl函数用来在红黑树中添加或者注销待监视文件描述符,最后调用epoll_wait函数直到有就绪的文件描述符立即返回给用户态进程

  • 时间复杂度O(1)
  • 文件描述符最大限制:能打开的fd的上限远大于10241G的内存上能监听约10w+
epoll的两种工作方式
  • 水平触发(LT):若就绪的事件一次没有处理完所有要做的事件,就会一直去处理。即就会将没有处理完的事件继续放回到就绪队列之中(即那个内核中的链表),一直进行处理
  • 边缘触发(ET) :就绪的事件只能处理一次,若没有处理完会在下次的其它事件就绪时再进行处理。而若以后再也没有就绪的事件,那么剩余的那部分数据也会随之而丢失。

ET模式的效率比LT模式的效率要高很多。只是如果使用ET模式,就要保证每次进行数据处理时,要将其处理完,不能造成数据丢失,这样对编写代码的人要求就比较高。 为了保证数据的完整性,ET模式只支持非阻塞的读写。

select、poll和epoll对比

实现机制 时间复杂度 连接数 传递方式
select O(n) 1024 内核-->用户
poll O(n) 无限制 内核-->用户
epoll O(1) 很大 共享内存

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

select、poll和epoll之间的区别的更多相关文章

  1. select、poll、epoll之间的区别总结

    select.poll.epoll之间的区别总结 05/05. 2014 select,poll,epoll都是IO多路复用的机制.I/O多路复用就通过一种机制,可以监视多个描述符,一旦某个描述符就绪 ...

  2. select、poll、epoll之间的区别

    select.poll.epoll之间的区别总结[整理]   select,poll,epoll都是IO多路复用的机制.I/O多路复用就通过一种机制,可以监视多个描述符,一旦某个描述符就绪(一般是读就 ...

  3. select、poll、epoll之间的区别(搜狗面试)

    (1)select==>时间复杂度O(n) 它仅仅知道了,有I/O事件发生了,却并不知道是哪那几个流(可能有一个,多个,甚至全部),我们只能无差别轮询所有流,找出能读出数据,或者写入数据的流,对 ...

  4. 网络篇:linux下select、poll、epoll之间的区别总结

    select.poll.epoll之间的区别总结 select,poll,epoll都是IO多路复用的机制.I/O多路复用就通过一种机制,可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪 ...

  5. [转帖] select、poll、epoll之间的区别总结[整理] + 知乎大神解答 https://blog.csdn.net/qq546770908/article/details/53082870 不过图都裂了.

    select.poll.epoll之间的区别总结[整理] + 知乎大神解答 2016年11月08日 15:37:15 阅读数:2569 http://www.cnblogs.com/Anker/p/3 ...

  6. (转)select、poll、epoll之间的区别

    本文来自:https://www.cnblogs.com/aspirant/p/9166944.html (1)select==>时间复杂度O(n) 它仅仅知道了,有I/O事件发生了,却并不知道 ...

  7. 转:select、poll、epoll之间的区别总结[整理]

    转:select.poll.epoll之间的区别总结[整理] select,poll,epoll都是IO多路复用的机制.I/O多路复用就通过一种机制,可以监视多个描述符,一旦某个描述符就绪(一般是读就 ...

  8. select,poll,epoll之间的区别

    (1)select,poll实现需要自己不断轮询所有fd集合,直到设备就绪,期间可能要睡眠和唤醒多次交替.而epoll其实也需要调用epoll_wait不断轮询就绪链表,期间也可能多次睡眠和唤醒交替, ...

  9. select、poll、epoll之间的区别总结[整理]

    select,poll,epoll都是IO多路复用的机制.I/O多路复用就通过一种机制,可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作.但select ...

随机推荐

  1. Java WebService(实战) 简单实例

    一.准备工作(以下为本实例使用工具) 1.MyEclipse10.7.1 2.JDK 1.6.0_22 二.创建服务端 1.创建[Web Service Project],命名为[TheService ...

  2. IDEA SonarLint安装及使用

    SonarLint插件安装IDEA菜单栏选择File->Settings,左边栏选择Plugins 在线安装选择Browse repositories,搜索Sonar,选择SonarLint进行 ...

  3. centos 6.5 上安装jdk

    1.首先明确自己的电脑上32位还是64位,自己的电脑是32位 2.下载jdk进入到oracle公司的主页 把页面拖到最下面 点击上面这个就可以下载以前比较低的版本 这里选择 32位的源码包的方式,将源 ...

  4. 7-4 是否同一棵二叉搜索树 (25分) JAVA

    给定一个插入序列就可以唯一确定一棵二叉搜索树.然而,一棵给定的二叉搜索树却可以由多种不同的插入序列得到. 例如分别按照序列{2, 1, 3}和{2, 3, 1}插入初始为空的二叉搜索树,都得到一样的结 ...

  5. 06[笔记] SpringBoot 删除Redis指定缓存

    /* ******************************************载入缓存开始************************************************* ...

  6. py4j.protocol.Py4JJavaError: An error occurred while calling z:org.apache.spark.api.python.PythonRDD.collectAndServe. : java.lang.IllegalArgumentException: Unsupported class file major version 55

    今天小编用Python编写Spark程序报了如下异常: py4j.protocol.Py4JJavaError: An error occurred while calling z:org.apach ...

  7. plsql截取字符串字段中的某个字符段

    截取字符串 字符串s=" hello world  ! (name) " 如果要截取括号中的字符串可以采取如下方法. select substr(s,instr(s,'(')+1, ...

  8. selenium(12)-web UI自动化项目实战(PO模式,代码封装)

    web UI自动化项目实战-项目 项目使用禅道,所以你需要搭建1个禅道,搭建禅道的方法和步骤见 https://www.cnblogs.com/xinhua19/p/13151296.html 搭建U ...

  9. 大型Java进阶专题(六)设计模式之代理模式

    代理模式 前言 又开始我的专题了,又停滞了一段时间了,加油继续吧.都知道 SpringAOP 是用代理模式实现,到底是怎么实现的?我们来一探究竟,并且自己仿真手写还原部分细节. 代理模式的应用 在生活 ...

  10. Redis基础01-redis的数据结构

    参考书:<redis设计与实现> Redis虽然底层是用C语言写的,但是底层的数据结构并不是直接使用C语言的数据结构,而是自己单独封装的数据结构: Redis的底层数据结构由,简单动态字符 ...