一、select

1.起源

select最早于1983年出现在4.2BSD中(BSD是早期的UNIX版本的分支)。

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

2.select的优点

目前几乎在所有的平台上支持,具有良好的跨平台支持。

3.select的缺点

  1. 单个进程能够监视的文件描述符的数量存在最大限制。默认情况下,在Linux上单个进程能够打开的最大文件数为1024.(可以通过修改宏定义甚至重新编译内核的方式提升这一限制)。
  2. select()所维护的存储大量文件描述符的数据结构,随着文件描述符数量的增大, 其复制的开销也线性增长。
  3. 由于网络相应时间的延迟使得大量的TCP连接处于非活跃状态,但调用select()会对所有socket进行一次线性扫描,浪费了一定的开销。
  4. select()所维护的socket连接,kernel中有数据了只会返回称有数据了,但不会指定socket,还需要对socket进行扫描,找到是哪些socket在kernel中准备了数据,浪费了开销。

二、poll

1.起源

poll在1986年诞生于System V Release 3,它和select在本质上没有多大差别,但是poll没有最大文件描述符数量的限制。

2.poll的优点

没有最大文件描述符数量的限制。

3.poll的缺点

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

4.poll的实际应用

在实际中,poll被认为是select,poll,epoll之间的一个过渡阶段,在实际中运用不多。

 

三、epoll

1.起源

epoll是在Linux2.6中提出的,是之前的select和poll的增强版本。

2.epoll的优点

相对于select和poll来说,epoll更加灵活,没有描述符限制。

epoll使用一个文件描述符管理多个描述符,将用户关系的文件描述符的事件存放到内核的一个事件表中,这样在用户空间和内核空间的copy只需一次。

epoll是由内核直接支持的实现方法,它几乎具备了之前所说的一切优点,被公认为Linux2.6下性能最好的多路I/O就绪通知方法。epoll是目前最流行的,目前知名框架Tornado,Nginx,Twisted等都是使用的epoll。

  1. epoll更加灵活,没有描述符限制。
  2. epoll可以同时支持水平触发和边缘触发(Edge Triggered,只告诉进程哪些文件描述符刚刚变为就绪状态,它只说一遍,如果我们没有采取行动,那么它将不会再次告知,这种方式称为边缘触发),理论上边缘触发的性能要更高一些,但是代码实现相当复杂。
  3. epoll同样只告知那些就绪的文件描述符,而且当我们调用epoll_wait()获得就绪文件描述符时,返回的不是实际的描述符,而是一个代表就绪描述符数量的值,你只需要去epoll指定的一个数组中依次取得相应数量的文件描述符即可,这里也使用了内存映射(mmap)技术,这样便彻底省掉了这些文件描述符在系统调用时复制的开销。
  4. 另一个本质的改进在于epoll采用基于事件的就绪通知方式。在select/poll中,进程只有在调用一定的方法后,内核才对所有监视的文件描述符进行扫描,而epoll事先通过epoll_ctl()来注册一个文件描述符,一旦基于某个文件描述符就绪时,内核会采用类似callback的回调机制,迅速激活这个文件描述符,当进程调用epoll_wait()时便得到通知。
如:epoll监控着100个socket,交给kernel去监测,如果kernel发现只有两个socket有数据,那么kernel会告诉用户具体是哪一个socket有数据,只需要循环去这两个活跃的socket中收取数据,节省了这部分的开销。

  注:水平触发和边缘触发(Level Triggered and Edge Triggered)

  水平触发Level Triggered:在kernel中数据准备好,处于ready的状态,如果进程没有对其进行IO操作,数据就还是在kernel中,只有进程再次发送一个recvfrom(system call),触发后才会将kernel中的就绪的数据拷贝到用户内存中去。

  边缘触发Edge Triggered:和水平触发相反,数据在kernel中ready后,如果进程没有对其进行IO操作,那么就不会再次return readable等信息给进程。数据还是在kernel中,并不会到用户内存中去。

3.epoll的缺点

仅在支持2.6内核的平台中支持。

Windows 不支持epoll,支持select。

四、select的代码实现

需求:用select实现一个简单的socketserver,可以实现多并发。

I/O多路复用之select,poll,epoll简介的更多相关文章

  1. IO多路复用之select poll epoll

    参考文档: http://blog.csdn.net/tennysonsky/article/details/45745887 select(),poll(),epoll()都是I/O多路复用的机制. ...

  2. Linux网络通信编程(套接字模型TCP\UDP与IO多路复用模型select\poll\epoll)

    Linux下测试代码: http://www.linuxhowtos.org/C_C++/socket.htm TCP模型 //TCPClient.c #include<string.h> ...

  3. 浅谈网络I/O多路复用模型 select & poll & epoll

    http://blog.csdn.net/nk_test/article/details/50662946

  4. Select/Poll/Epoll异步IO

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

  5. Linux IO模式以及select poll epoll详解

    一 背景 同步IO和异步IO,阻塞IO和非阻塞IO分别是什么,到底有什么区别?不同的人在不同的上下文下给出的答案是不同的.所以先限定一下本文的上下文. 本文讨论的背景是Linux环境下的network ...

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

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

  7. IO多路复用select/poll/epoll详解以及在Python中的应用

    IO multiplexing(IO多路复用) IO多路复用,有些地方称之为event driven IO(事件驱动IO). 它的好处在于单个进程可以处理多个网络IO请求.select/epoll这两 ...

  8. Python异步非阻塞IO多路复用Select/Poll/Epoll使用,线程,进程,协程

    1.使用select模拟socketserver伪并发处理客户端请求,代码如下: import socket import select sk = socket.socket() sk.bind((' ...

  9. Linux 网络编程的5种IO模型:多路复用(select/poll/epoll)

    Linux 网络编程的5种IO模型:多路复用(select/poll/epoll) 背景 我们在上一讲 Linux 网络编程的5种IO模型:阻塞IO与非阻塞IO中,对于其中的 阻塞/非阻塞IO 进行了 ...

随机推荐

  1. 各种版本docker下载的中国开源地址

    最近在群里听说Docker很火,于是自己抱着试试的态度,想玩玩,可是遇到了一些问题,记录下来,方便备忘,也方便防止大家被坑. 我的虚拟机装的是centos 6.5,百度了好多教程,丫的,都不解释,就一 ...

  2. spring中BeanPostProcessor之一:InstantiationAwareBeanPostProcessor(03)

    前面介绍了InstantiationAwareBeanPostProcessor后置处理器的postProcessBeforeInstantiation和postProcessAfterInstant ...

  3. 【PHP】PHP基本语法

    一.什么是PHP? a)    定义:PHP就是超文本预处理器 b)    超文本:我们前边8天学习的内容其实就是超文本内容 c)    预处理器:相当于牛奶在工厂加工的过程,我们虽然不可见,但是我们 ...

  4. 微信小程序template富文本插件image宽度被js强制设置

    这段时间一直做微信小程序,过程中遇到了一个问题,这个问题一直没有得到完美的解决. 问题描述: 在Web编程中经常会引入template插件,这个插件是封装好,我们通常的做法是直接引入,配置简单,好用, ...

  5. hadoop(六)rsync远程同步|xsync集群分发(完全分布式准备三)|8

    前置环境准备:centos7克隆ip|机器名|映射关系|别名配置(hadoop完全分布式准备一)scp命令copy文件和配置(hadoop完全分布式准备二) rsync远程同步工具 优点 rsync主 ...

  6. Python线程和协程CPU资源利用率测试

    前言介绍 协程 ,又称为微线程,它是实现多任务的另一种方式,只不过是比线程更小的执行单元.因为它自带CPU的上下文,这样只要在合适的时机,我们可以把一个协程切换到另一个协程.通俗的理解: 在一个线程中 ...

  7. [leetcode]1379. Find a Corresponding Node of a Binary Tree in a Clone of That Tree

    [leetcode]1379. Find a Corresponding Node of a Binary Tree in a Clone of That Tree 链接 leetcode 描述    ...

  8. HBase-2.2.3源码编译-Windows版

    源码环境一览 windows: 7 64Bit Java: 1.8.0_131 Maven:3.3.9 Git:2.24.0.windows.1 HBase:2.2.3 Hadoop:2.8.5 下载 ...

  9. list 的sublist 隐藏 bug

    list A = new list(); list a = A.sublist(0,3); 假如对a进行增加或者删除 会 同样改变A里的值,即其实a仅仅是A的一个试图,而不是一个新的list 对象,所 ...

  10. 【python系统学习14】类的继承与创新

    目录: 目录: [toc] 类的继承 子类和父类 继承的写法 继承示例 父类可以被无限个子类所继承 子类实例可调用父类属性和方法 类的始祖(根类) 根类 - object 实例归属判断 - isins ...