笔记-select,poll,epoll

1.      I/O多路复用

I/O多路复用是指:通过一种机制或一个进程,可以监视多个文件描述符,一旦描述符就绪(写或读),能够通知程序进行相应的读写操作。

linux中的select,poll,epoll都是IO多路复用的具体实现。

1.1.  select

select最早出现在4.2BSD中,通过一个select()系统调用来监视多个文件描述符的数组,当select()返回后,该数组中就绪的文件描述符便会被内核修改标志位,使进程可以获得这些文件描述符而进行后续操作。

select的缺点:

  1. 每次调用select,需要把fd集合从用户态拷贝到内核态,这个开销在fd很多时会很大;
  2. 每次调用select后需要在内核遍历传递进来的所有fd,这个开销在fd很多时也很大;
  3. 单个进程能够监视的文件描述符数量存在最大限制,在linux上一般为1024; select返回的是含有整个句柄的数组,应用程序需要遍历整个数组才能发现哪些句柄发生了事件;

1.2.    poll

poll在1986年诞生于System V Release 3,它的实现和select非常相似,只是描述fd集合的方式不同,poll使用pollfd结构而不是select的fd_set结构,其他的都差不多。因为pollfd是链表式的,所以poll没有最大文件描述符数量的限制,除了这一点,其它特性和select一样。

poll和select同样存在一个缺点就是,包含大量文件描述符的数组被整体复制于用户态和内核的地址空间之间,而不论这些文件描述符是否就绪,它的开销随着文件描述符数量的增加而线性增大。另外,select()和poll()将就绪的文件描述符告诉进程后,如果进程没有对其进行IO操作,那么下次调用select()和poll()的时候将再次报告这些文件描述符,所以它们一般不会丢失就绪的消息,这种方式称为水平触发(Level Triggered)。

1.3.    epoll

在linux2.6(准确来说是2.5.44)由内核直接支持的方法。epoll解决了select和poll的缺点。

  1. 最大描述符数量限制,epoll没有这个限制,它所支持的fd上限是最大可以打开文件的数目,具体数目可以cat /proc/sys/fs/file-max查看,一般来说这个数目和系统内存关系比较大;
  2. 重复拷贝问题:每次注册新的事件到epoll中时,会把所有的fd拷贝进内核,而不是在等待的时候重复拷贝,保证了每个fd在整个过程中只会拷贝1次。
  3. 遍历问题:epoll的解决方法不像select和poll每次对所有fd进行遍历轮询所有fd集合,而是在注册新的事件时,为每个fd指定一个回调函数,当设备就绪的时候,调用这个回调函数,这个回调函数就会把就绪的fd加入一个就绪表中。(所以epoll实际只需要遍历就绪表)。

epoll同时支持水平触发和边缘触发:

  1. 水平触发(level-triggered):只要满足条件,就触发一个事件(只要有数据没有被获取,内核就不断通知你)。e.g:在水平触发模式下,重复调用epoll.poll()会重复通知关注的event,直到与该event有关的所有数据都已被处理。(select, poll是水平触发, epoll默认水平触发)
  2. 边缘触发(edge-triggered):每当状态变化时,触发一个事件。e.g:在边沿触发模式中,epoll.poll()在读或者写event在socket上面发生后,将只会返回一次event。调用epoll.poll()的程序必须处理所有和这个event相关的数据,随后的epoll.poll()调用不会再有这个event的通知。

2. 附录

2.1.  水平触发与边缘触发

在linux的IO多路复用中有水平触发,边缘触发两种模式,这两种模式的区别如下:

水平触发:如果文件描述符已经就绪可以非阻塞的执行IO操作了,此时会触发通知.允许在任意时刻重复检测IO的状态,没有必要每次描述符就绪后尽可能多的执行IO.select,poll就属于水平触发.

边缘触发:如果文件描述符自上次状态改变后有新的IO活动到来,此时会触发通知.在收到一个IO事件通知后要尽可能多的执行IO操作,因为如果在一次通知中没有执行完IO那么就需要等到下一次新的IO活动到来才能获取到就绪的描述符.信号驱动式IO就属于边缘触发.

epoll既可以采用水平触发,也可以采用边缘触发.

举例说明:一个管道收到了1kb的数据,epoll会立即返回,此时读了512字节数据,然后再次调用epoll.这时如果是水平触发的,epoll会立即返回,因为有数据准备好了.如果是边缘触发的不会立即返回,因为此时虽然有数据可读但是已经触发了一次通知,在这次通知到现在还没有新的数据到来,直到有新的数据到来epoll才会返回,此时老的数据和新的数据都可以读取到(当然是需要这次你尽可能的多读取).

笔记-select,poll,epoll的更多相关文章

  1. select, poll, epoll笔记

    看网络通信框架,netty, thrift,java nio等,最后都会通过select, poll, epoll或者socket等进行通信.查了些网页,总结一下.做个笔记 1. Socket单线程阻 ...

  2. Select/Poll/Epoll异步IO

    IO多路复用 同步io和异步io,阻塞io和非阻塞io分别是什么,有什么样的区别? io模式 对于一次io 访问(以read为例),数据会先拷贝到操作系统内核的缓冲区,然后才会从操作系统内核的缓冲区拷 ...

  3. select/poll/epoll on serial port

    In this article, I will use three asynchronous conferencing--select, poll and epoll on serial port t ...

  4. Linux下select&poll&epoll的实现原理(一)

    最近简单看了一把 linux-3.10.25 kernel中select/poll/epoll这个几个IO事件检测API的实现.此处做一些记录.其基本的原理是相同的,流程如下 先依次调用fd对应的st ...

  5. Python之路-python(Queue队列、进程、Gevent协程、Select\Poll\Epoll异步IO与事件驱动)

    一.进程: 1.语法 2.进程间通讯 3.进程池 二.Gevent协程 三.Select\Poll\Epoll异步IO与事件驱动 一.进程: 1.语法 简单的启动线程语法 def run(name): ...

  6. 多进程、协程、事件驱动及select poll epoll

    目录 -多线程使用场景 -多进程 --简单的一个多进程例子 --进程间数据的交互实现方法 ---通过Queues和Pipe可以实现进程间数据的传递,但是不能实现数据的共享 ---Queues ---P ...

  7. Python自动化 【第十篇】:Python进阶-多进程/协程/事件驱动与Select\Poll\Epoll异步IO

    本节内容: 多进程 协程 事件驱动与Select\Poll\Epoll异步IO   1.  多进程 启动多个进程 进程中启进程 父进程与子进程 进程间通信 不同进程间内存是不共享的,要想实现两个进程间 ...

  8. select,poll,epoll的归纳总结区分

    Select.Poll与Epoll比较 以下资料都是来自网上搜集整理.引用源详见文章末尾. 1 Select.Poll与Epoll简介 Select select本质上是通过设置或者检查存放fd标志位 ...

  9. 转一贴,今天实在写累了,也看累了--【Python异步非阻塞IO多路复用Select/Poll/Epoll使用】

    下面这篇,原理理解了, 再结合 这一周来的心得体会,整个框架就差不多了... http://www.haiyun.me/archives/1056.html 有许多封装好的异步非阻塞IO多路复用框架, ...

随机推荐

  1. 腾讯bugly 映射用法

    package com.tencent.bugly.agent; import android.app.Activity; import android.content.Context; import ...

  2. 第五章 存储过程&触发器

    1.前言 2.存储过程和触发器->存储过程 ·理解:是一组SQL命令集合,经过预编译存放在系统中:就像java程序里的方法,可以重复的被调用: 在日常的数据库操作中,会有大量的T-SQL批处理. ...

  3. strdup和strndup函数

    首先说明一下:这两个函数不建议使用,原因是返回内存地址把释放权交给别的变量,容易忘记释放. 一.strdup函数 函数原型 头文件:#include <string.h> char *st ...

  4. windows10家庭中文版升级专业版或企业版简单方便的操作方法

    以管理员的身份运行cmd 1 ,升级到专业版输入:slmgr /ipk W269N-WFGWX-YVC9B-4J6C9-T83GX 输入slmgr.vbs -skms zh.us.to 激活 2, 升 ...

  5. mysql语句的相关操作整理

    事实证明,如果不经常跟代码,语句打交道,人家可是会翻脸不认人的,大脑也会觉得一脸懵逼,不知道做错了啥,这次长点记性了,把语句整理出来,不仅加强对sql语句的记忆,还能有个笔记,以后大脑懵逼了还能回来看 ...

  6. session的MaxInactiveInterval=0在tomcat6和tomcat8不同表现

    在tomcat6中调用 request.getSession().setMaxInactiveInterval(0); 这个session会立即过期. 而在tomcat8中,同样的调用,会导致这个se ...

  7. 译:Local Spectral Graph Convolution for Point Set Feature Learning-用于点集特征学习的局部谱图卷积

    标题:Local Spectral Graph Convolution for Point Set Feature Learning 作者:Chu Wang, Babak Samari, Kaleem ...

  8. 剑指offer28 字符串的排列

    1.全局变量可以在最后去定义并初始化,不一定非要在开头 2.此题有一种特殊情况需要考虑,比如字符串是“aa”,那输出应该是“aa”,而不是“aa,aa”,即相同的不输出.实现这个处理用了c++中的容器 ...

  9. linq 和 lmabda 表达式 的用法 和优劣 转自 农码一生

    https://www.cnblogs.com/zhaopei/p/5746414.html

  10. linq 查询的两种方法 (在EF model中实现)

    众所周知:linq查询有两种方式 1.通过linq表达式查询 2.是通过linq方法查询 代码中 每一步都有注释