一、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. 《Three.js 入门指南》2- 照相机

    2.1 什么是照相机 我们使用Three.js创建的场景是三维的,而通常情况下显示屏是二维的,那么三维的场景如何显示到二维的显示屏上呢?照相机就是这样一个抽象,它定义了三维空间到二维屏幕的投影方式,用 ...

  2. Spring Framework之事务管理

    目录 问题 数据库事务 事务的定义 事务的目的 事务的特性 事务隔离级别 数据并发问题 事务隔离级别对数据并发问题的作用 快照读 Spring事务管理 事务管理接口 TransactionDefini ...

  3. hacknos-player靶机渗透

    靶机下载地址https://www.vulnhub.com/entry/hacknos-player,459/ 网络配置 该靶机可能会存在无法自动分配IP的情况,所以无法扫描到的情况下需要手动配置获取 ...

  4. EntityFramework Core 3.x上下文构造函数可以注入实例呢?

    前言 今天讨论的话题来自一位微信好友遇到问题后请求我的帮助,当然他的意图并不是本文标题,只是我将其根本原因进行了一个概括,接下来我们一起来探索标题的问号最终的答案是怎样的呢? 上下文构造函数是否可以注 ...

  5. 使用 python 创建&更改 word 文档

    使用 python 修改 word 文档 说明:这个需求是老师想要一个自动识别 word 文档中指定位置的分数,并填入相应表格. 使用库 python-docx 的官方文档地址是:python-doc ...

  6. go 结构开发规范

    机构规范: // 当前程序的包名 package main //导入其他的包 import "fmt" //常量的定义 const PI=3.14 //全局变量的声明和赋值 var ...

  7. NullPointerException的处理新方式,Java14真的太香了

    在Java语言中,处理空指针往往是一件很头疼的事情,一不小心,说不定就搞出个线上Bug,让你的绩效考核拿到3.25.最近新出的Java14,相信大家都有所耳闻,那么今天就来看看,面对NullPoint ...

  8. Struts2-学习笔记系列(9)-OGNL类型转换和类型绑定

    HTML: <s:form action="login"> <s:textfield name="user.name" label=" ...

  9. 数据结构和算法(Golang实现)(3)简单入门Golang-流程控制语句

    流程控制语句 计算机编程语言中,流程控制语句很重要,可以让机器知道什么时候做什么事,做几次.主要有条件和循环语句. Golang只有一种循环:for,只有一种判断:if,还有一种特殊的switch条件 ...

  10. Spring Boot 和 Spring Cloud 应用内存如何管理?

    在整体应用架构中,非生产环境情况下,一般 1GB 或者 2GB 的 RAM 就足够了.如果我们将这个应用程序划分为 20 或 30 个独立的微服务,那么很难期望 RAM 仍将保持在 1GB 或 2GB ...