select poll epoll

2023-11-06

Select

select本质上是通过设置或者检查存放fd标志位的数据结构来进行下一步处理。用Select就可以完成非阻塞(所谓非阻塞方式non-block,就是进程或线程执行此函数时不必非要等待事件的发生,select在socket编程中还是比较重要的。一旦执行肯定返回,以返回值的不同来反映函数的执行情况,如果事件发生则与阻塞方式相同,若事件没有发生则返回一个代码来告知事件未发生,而进程或线程继续执行,所以效率较高)方式工作的程序,它能够监视我们需要监视的文件描述符的变化情况——读写或是异常!!

select模型的特点:
(1) FD连接数量:单个进程可监视的fd数量被限制(支持最大连接数1024(x86) or 2048(x64));
(2) I/O效率:返回的可读集合是个fdset类型,需要对所有的监听读句柄一一进行FD_ISSET的测试来判断是否可读; 对描述符进行扫描时是线性扫描,比较耗时,时间复杂度线性增加,每次调用进行线性遍历,时间复杂度为O(N)。比如如果只监听0和1000两个句柄,select需要遍历1001个句柄来检查事件。
select需要对所有的监听读句柄扫描判断是否是自己关心的一一进行FD_ISSET的测试来判断是否可读,是否发生了事件;
(3) 空间效率:FD每次都全部拷贝。需要维护一个用来存放大量fd的数据结构,这样会使得用户空间和内核空间在传递该结构时复制开销大

Poll

poll模型的特点:
(1) FD连接数量:Poll没有最大连接数的限制,
(2) I/O效率:poll运行过程中,也是将用户传入的数组拷贝到内核空间,然后查询每个fd对应的设备状态,如果设备就绪则在设备等待队列中加入一项并继续遍历,如果遍历完所有fd后没有发现就绪设备,则挂起当前进程,直到设备就绪或者主动超时,被唤醒后它又要再次遍历fd。这个过程经历了多次无谓的遍历,每次调用进行线性遍历,时间复杂度为O(N);原因是它是基于链表来存储的,但是同样有一个缺点:大量的fd的数组被整体复制于用户态和内核地址空间之间,而不管这样的复制是不是有意义。poll还有一个特点是“水平触发”,如果报告了fd后,没有被处理,那么下次poll时会再次报告该fd。
(3)空间效率:FD每次poll都拷贝。

1、和select相比,poll的优点是:
(1) 不再局限于FD_SETSIZE个监听描述符,只要能打开的描述符,都可以监听;
(2) 监听描述符集合不再是值结果参数,而是event表示监听事件,revents表示触发的事件;
(3) poll的效率比select稍高(poll只遍历输入的监听数组中的描述符,如果数组中的fd<0,则poll忽略fd,当监听的描述符离散时效率稍高于select。比如监听0和1000两个句柄,则poll只需要遍历两个描述符,而select需要遍历1001个描述符;当监听描述符连续时,poll和select效率相当,底层实现也是一致的)。

解决了select中的问题(1),一定程度上也解决了(2),比如如果只监听0和1000两个句柄,select需要遍历2个描述符来检查事件,而select需要1001次。

2、poll和select共同的问题是性能较差:

(1)遍历所有的文件描述符,当监听描述符个数增加时,监听效率降低,
(2)并且select和poll每次都要在用户态和内核态拷贝监听的描述符参数。

Epoll

  epoll是为处理大批量句柄而作了改进的poll。是提高内核I/O性能的新方法。当同时需要保持很多的长连接,而且连接的开关很频繁时,就能够发挥epoll最大的优势了。在一些 benchmark中,如果所有的socket基本上都是活跃的---比如一个高速LAN环境,epoll并不比select/poll有什么效率,相 反,如果过多使用epoll_ctl,效率相比还有稍微的下降。但是一旦使用idle connections模拟WAN环境,空闲的连接量十分大,偶尔蹦出来几个活跃的客户端,epoll的效率就远在select/poll之上了。它是在2.5.44内核中被引进的:
  1. int epoll_create(int size);
    注:当创建好epoll句柄后,它就是会占用一个fd值,在linux下如果查看/proc/进程id/fd/,是能够看到这个fd的,所以在使用完epoll后,必须调用close()关闭,否则可能导致fd被耗尽。

  2. int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
    epoll的事件注册函数,它不同于select()是在监听事件时告诉内核要监听什么类型的事件,而是在这里先注册要监听的事件类型。
    第一个参数是epoll_create()的返回值。
    第二个参数表示动作,用三个宏来表示:
    EPOLL_CTL_ADD:注册新的fd到epfd中;
    EPOLL_CTL_MOD:修改已经注册的fd的监听事件;
    EPOLL_CTL_DEL:从epfd中删除一个fd;
    第三个参数是需要监听的fd。
    第四个参数是告诉内核需要监听什么事,struct epoll_event结构

  3. int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout);
    收集在epoll监控的事件中已经发送的事件。参数events是分配好的epoll_event结构体数组,epoll将会把发生的事件赋值到events数组中(events不可以是空指针,内核只负责把数据复制到这个events数组中,不会去帮助我们在用户态中分配内存)。maxevents告之内核这个events有多大,这个 maxevents的值不能大于创建epoll_create()时的size,参数timeout是超时时间(毫秒,0会立即返回,-1将不确定,也有说法说是永久阻塞)。如果函数调用成功,返回对应I/O上已准备好的文件描述符数目,如返回0表示已超时。

  4. 相比与select和poll模型,epoll模型的优点:
    (1) FD连接数量:Epoll它没有最大连接数的限制,只受进程打开描述符总数的限制;
    (2)I/O效率:epoll支持水平触发和边缘触发,最大的特点在于边缘触发,它只告诉进程哪些fd刚刚变为就绪态,并且只会通知一次。还有一个特点是,epoll使用“事件”的就绪通知方式,通过epoll_ctl注册fd,一旦该fd就绪,返回参数中就是触发事件的列表,不用再遍历输入事件表查询各个事件是否被触发。内核就会采用类似callback的回调机制来激活该fd,epoll_wait便可以收到通知。时间发复杂度O(1)
    (3)空间效率:调用epoll_ctl时拷贝进内核并由内核保存,之后每次epoll_wait不拷贝,使用共享内存的方式,不在用户和内核之间反复传递监听的描述符信息;epoll使用 mmap减少复制开销。
    (4)监听性能不随着监听描述符数的增加而增加,是O(1)的,不再是轮询描述符来探测事件,而是由描述符主动上报事件;
    epoll显著提高性能的前提是:监听大量描述符,并且每次触发事件的描述符文件非常少。
  5. select、poll和epoll性能PK
    (1)、epoll模型的最大特点就是没有setfpdsize大小的限制;
    而select有大小的限制1024个;可以在修改内核的大小,但是资料显示这个会导致效率下降;还可以选择多进程 ,但是多进程之间的数据的同步和开销在大量的连接请求上的效率是比较低下的;可以在ect/ frofile/maxfile中查看最大的数量,这个值一般和内存有很大的关系,比如1GB的内存大概有10万个FD文件描述符,句柄;
    (2)、IO 效率不随FD数目增加而线性下降
    二是基于事件的通知机制而不是线性扫描,内核采用回调函数callback来调用相应的处理函数。传统的select和poll模型中进程只有在调用一定的方法后,内核才对所有监视的文件描述符进行扫描,并且会随着fd数量的增加而使其效率线性下降,因为poll和select是线性的扫描各个文件描述符来实现的;而epoll事先通过epoll_ctl()来注册一个文件描述符,一旦基于某个文件描述符就绪时,内核会采用类似callback的回调机制,迅速激活这个文件描述符,当进程调用epoll_wait()时便得到通知。
    (3)、使用mmap加速内核 与用户空间的消息传递。

采用mmap技术省去了结构体FD从用户态向内核态空间复制的时间内存开销。epoll模型使用mmap加速内核与用户之间的消息传递;避免了传统的select、和poll的一些不必要的内存拷贝,类似fork的(Copy-On-Write)COW技术一样,epoll和用户是公用一块内存空间实现的;
注:使用mmap加速内核 与用户空间的消息传递。mmap是将一个文件和对象映射到内存下;

四、epoll的两种工作支持水平触发和边沿触发。

       LT(Level Triggered) 水平触发是epoll缺省的工作方式,并且同时支持block和no-block socket.在这种做法中,内核告诉你一个文件描述符是否就绪了,然后你可以对这个就绪的fd进行IO操作。如果你不作任何操作,内核还是会继续通知你的,所以,这种模式编程出错误可能性要小一点。传统的select/poll都是这种模型的代表.

       ET (edge-triggered) 是高速工作方式,只支持no-block socket,它效率要比LT更高(该模式的工作原理决定了它只能支持非阻塞模式)。ET与LT的区别在于,当一个新的事件到来时,ET模式下当然可以从epoll_wait调用中获取到这个事件,可是如果这次没有把这个事件对应的套接字缓冲区处理完,在这个套接字中没有新的事件再次到来时,在ET模式下是无法再次从epoll_wait调用中获取这个事件的。而LT模式正好相反,只要一个事件对应的套接字缓冲区还有数据,就总能从epoll_wait中获取这个事件。因此,LT模式下开发基于epoll的应用要简单些,不太容易出错。而在ET模式下事件发生时,如果没有彻底地将缓冲区数据处理完,则会导致缓冲区中的用户请求得不到响应。在LT-水平触发和缺省模式下,只要是该缓冲区中有数据,则总是能从epoll_wait中获取该事件。显的就比较安全。

简而言之:

  水平触发(level-triggered)——只要满足条件,就触发一个事件(只要有数据没有被获取,内核就不断通知你);

   边缘触发(edge-triggered)——每当状态变化时,触发一个事件。

例如:
1. 我们已经把一个用来从管道中读取数据的文件句柄(RFD)添加到epoll描述符
2. 这个时候从管道的另一端被写入了2KB的数据
3. 调用epoll_wait(2),并且它会返回RFD,说明它已经准备好读取操作
4. 然后我们读取了1KB的数据
5. 调用epoll_wait(2)……

     若是LT工作方式,内核会继续通知你RFD句柄就绪,里面还有1KB的数据没有读处理;但是若是ET工作方式,内核将只会通知一遍,剩下的IKB数据在下一RFD句柄没有新的活动(数据的发送或接受)的情况下,就不会被应用程序处理,造成请求得不到响应。所以对于ET触发的,fd必须是非阻塞式的,这样可以一次把数据读完,如果是阻塞式的,说不定则会读到阻塞;

五、epoll使用注意问题:

注意一:
int epoll_create(int size); //创建epoll文件描述符
参数size并不是限制了epoll所能监听的描述符最大个数,只是对内核初始分配内部数据结构的一个建议。返回是epoll描述符。-1表示创建失败。

注意二:
int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout);
//等待epfd上的io事件,最多返回maxevents个事件

注意三:
epoll监听ET事件时,fd必须是非阻塞套接口。比如监听可读事件,当ET上报可读后,需要一直读fd直到遇到EAGAIN错误为止,以免遗留数据在缓冲区中。如果fd是阻塞的, 则会读到阻塞了。

EAGAIN错误对于非阻塞套接口来说不是错误,只是说没有数据可读或者没有空间可写。

EWOULDBLOCK就是EAGAIN,值都是11。

selset/poll/epoll的LT模式监听的fd可以是阻塞模式的(因为只要满足条件,数据没有读完,内核就会持续通知你)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

select poll epoll 的相关文章

  • Http中Content-Type等属性详解

    前言 一直以来对HTTP请求中各种属性一知半解 偶然在博客中找到一篇 特意摘录过来方便自己以后查看 正文 敬请关注博客 后期不断更新优质博文 谢谢 这里讲解Content Type的可用值 以及在spring MVC中如何使用它们来映射请求
  • 嵌入式编写TCP连接过程

    先来一个三次握手和四次挥手 嵌入式连接过程 1 af 为地址族 Address Family 也就是 IP 地址类型 常用的有 AF INET 和 AF INET6 AF 是 Address Family 的简写 INET是 Inetnet
  • NIO效率高的原理之零拷贝与直接内存映射

    前言 在笔者上一篇博客 详解了NIO 并总结NIO相比BIO的效率要高的三个原因 点击查看 这篇博客将针对第三个原因 进行更详细的讲解 首先澄清 零拷贝与内存直接映射并不是Java中独有的概念 并且这两个技术并不是等价的 零拷贝 零拷贝是指
  • getaddrinfo简单应用——取得IP地址

    转自 http biancheng dnbcw info linux 265956 html 一个域名可能对应好几个ip地址 a out www baidu com 115 239 210 27 115 239 211 112 getadd
  • 【网络编程·应用层】https协议——加密与窃密的攻防战

    需要云服务器等云产品来学习Linux的同学可以移步 gt 腾讯云 lt gt 阿里云 lt gt 华为云 lt 官网 轻量型云服务器低至112元 年 新用户首次下单享超低折扣 目录 一 https协议的介绍 二 加密和解密 1 加密和解密的
  • libevent(6)windows上使用iocp网络模型

    windows操作系统上不能使用epoll模型 只能使用iocp网络模型 这里我把怎么在windows上使用iocp的代码直接贴上 include
  • Unix网络编程5种IO模型

    IO模型 用一幅图表示所支持的I O模型 纵向维度是 阻塞 Blocking 非阻塞 Non blocking 横向维度是 同步 异步 总结起来是四种模型 同步阻塞 同步非阻塞 异步阻塞 异步非阻塞 Unix网络编程 中划分出了 第五种 模
  • libev学习系列之三:libev编译安装

    libev学习系列之三 libev编译安装 版本说明 版本 作者 日期 备注 0 1 ZY 2019 5 31 初稿 目录 文章目录 libev学习系列之三 libev编译安装 版本说明 目录 源码结构 正常编译 交叉编译 源码结构 4 2
  • C# 网络编程之webBrowser乱码问题及解决知识

    在使用PHP MySQL编写网页时 曾近就因为显示中文乱码 口口口 困扰我很长时间 没想到在C 制作浏览器或获取XML页面时也经常会遇到显示中文乱码的问题 可想而知怎样解决编码问题或统一编码问题是非常严重的问题 下面就讲讲我的一些理解及解决
  • TCP的粘包问题

    TCP transport control protocol 传输控制协议 是面向连接的 面向流的 提供高可靠性服务 收发两端 客户端和服务器端 都要有一一成对的socket 因此 发送端为了将多个发往接收端的包 更有效的发到对方 使用了优
  • TFTP协议下载实验

    include
  • TCP/IP编程之SO_REUSEADDR和SO_REUSEPORT套接字选项

    基本概念 SO REUSEADDR套接字选项能起到以下4个不同的功用 1 SO REUSEADDR允许启动一个监听服务器并捆绑众所周知端口 即使以前建立的该端口用作它们的本地端口的连接仍存在 这个条件通常是这样碰到的 a 启动一个监听服务器
  • Linux I/O多路复用——poll模型实现服务端Socket通信

    目录 poll函数 参数说明 events相关 与select的不同 程序流程 程序实例 poll函数 poll模型在实现服务端时思路是和select类似的 可以说poll是select的加强版 poll函数原型如下 int poll st
  • Linux实现多进程服务端Socket通信

    目录 程序流程 程序实例 运行结果 本例主要是让服务器能够同时处理多个客户端的连接请求 程序流程 1 创建基本的套接字 并绑定地址信息 设置监听 2 循环accept来接收连接请求 每接收一个连接请求 就创建一个子进程 3 在子进程中进行客
  • 一起来学nginx(一)

    一起来学nginx 一 nginx概述 nginx是一款web服务器 相当于一个软件 除了nginx还有哪些web服务器 apche openresty nginx的优点 高并发 高性能 可扩展性好 nginx是模块化的 可靠性 热部署 在
  • 并发编程概览

    由于内容较多 将会分成多篇文章详述 可移步查看 操作系统发展史 多道技术 进程理论 进程的并行与并发 进程的三状态 同步与异步 阻塞与非阻塞 同步异步与阻塞非阻塞 创建进程的多种方式 join方法 进程间数据默认隔离 进程间通信IPC机制
  • Node.js开发入门—HTTP文件服务器

    HelloWorld示例只有演示意义 这次我们来搞一个实际的例子 文件服务器 我们使用Node js创建一个HTTP协议的文件服务器 你可以使用浏览器或其它下载工具到文件服务器上下载文件 用Node js实现的HTTP文件服务器 比我在Qt
  • HTTPS 的加密流程

    目录 一 HTTPS是什么 二 为什么要加密 三 加密 是什么 四 HTTPS 的工作过程 1 对称加密 2 非对称加密 3 中间人攻击 4 证书 总结 一 HTTPS是什么 HTTPS Hyper Text Transfer Protoc
  • 网络编程是什么

    转载 http peixun eol cn company company article detail php articleid 15033 对于初学者 或者没有接触过网络编程的程序员 会觉得网络编程涉及的知识很高深 很难 其实这是一种
  • mongos、nanomsg、zeroMQ简述和go-mongos使用实例

    mongos nanomsg zeroMQ简述和go mongos使用实例 文章目录 mongos nanomsg zeroMQ简述和go mongos使用实例 1 mongos nanomsg简述 2 zeroMQ nanomsg和可扩展

随机推荐

  • 51单片机---IE寄存器,TCON寄存器,TMOD寄存器

    寄存器IE 中断允许寄存器IE的作用 是控制所有中断源的开放或禁止 以及每个中断源是否被允许 寄存器IE的位格式如下 EX0 外部中断0允许位 EX0 1 允许外部中断0中断 EX0 0 禁止外部中断0中断 ET0 T0溢出中断允许位 ET
  • KNN学习之图像分类与KNN原理

    点击上方 小白学视觉 选择加 星标 或 置顶 重磅干货 第一时间送达 简介 KNN算法 即K近邻算法是一种监督学习算法 本质上是要在给定的训练样本中找到与某一个测试样本A最近的K个实例 然后统计k个实例中所属类别计数最多的那个类 就是A的类
  • Java进阶(2) - 特殊对象(Class类)

    存在的意义位于java lang包下 和java lang reflect包下的类共同支持java反射功能jvm在类加载时 在堆中为每个类生成一个Class对象 用于记录每个类的属性 方法等信息 同时每个对象生成时都有特殊的标记位来指向堆中
  • js预编译习题解题思路

    js预编译习题解题思路 function fn a c console log a function a var a 123 console log a 123 console log c function c function a if
  • Linux知识概括

    Linux知识概括 Linux介绍 VMware工具与远程登录 Linux目录结构 Vi和Vim编辑器 开关机与登录注销与用户管理 Linux常用系统文件 实用指令 其他常用指令 帮助指令 文件目录类 时间日期类 搜索查找类 压缩和解压类
  • Spring AOP如何使用AspectJ注解进行开发呢?

    转自 Spring AOP如何使用AspectJ注解进行开发呢 下文讲述Spring AspentJ中采用注解的方式定义切面 切入点和增强处理的示例 Annotation注解 注解名称 备注 Aspect 用于定义一个切面 Pointcut
  • 字节跳动P0级事故:实习生删除GB以下所有模型,直接上了今日头条......

    大家好 我是小猿 曾经我招过一个实习生 他曾经干过一件让我感到匪夷所思的事 我当时忙 让他把服务器重启 他直接来了个电源重启 最近脉脉上有网友爆料 字节跳动一位实习生删除了公司所有轻量级别的机器学习模型 什么是lite模型 该楼主表示 li
  • mysql优化之为什么我limit10也会全表扫描

    先上结果 优化前 优化后 工作中有一个业务场景一条命中记录会存储到一张命中记录A表 并且推送给用户 每一条推送记录存储到B表 AB是一对多的关系 现在一条sql语句是用户查看命中记录列表 按照命中的时间倒序排序 表结构如下 A表 CREAT
  • 上传大文件(文件流分段上传、base64分段转码)

    java http方式上传大文件 文件流分段上传 base64分段转码 李梦成的博客 CSDN博客 java 分块上传
  • 哪些因素影响阻抗控制?网格铜的妙用

    原文来自微信公众号 工程师看海 前文介绍了传输线 特性阻抗以及信号的反射概念 如果阻抗不连续信号会发生反射严重时将会导致系统不能正常工作 都有哪些参数会影响阻抗呢 了解相关参数后我们就可以知道有哪些方法来控制阻抗了 线宽W 走线加宽 则单位
  • sizeof笔试题

    http www xici net b700278 d44576087 htm 1 常规 char str1 Hello char str2 5 H e l l o char str3 6 H e l l o 0 char p1 Hello
  • Android有线IPV6总结(二):内核中RS与RA的一点学习

    RS Router Solicitation路由器请求 RA Router Advertisement路由器公告 在Android系统中我们想要打开一个网络接口 比如eth0 的ipv6功能 用命令的话我们有如下两种办法 1 echo 0
  • vscode ( Visual Studio Code )设置中文、字体和字号

    全拼是 Visual Studio Code 简称 VS Code 是由微软研发的一款免费 开源的跨平台代码编辑器 目前是前端 网页 开发使用最多的一款软件开发工具 下载网址 https code visualstudio com Down
  • WeChat结合文档开发

    1 获取accessToken 2 根据测试号给的ID和秘钥 生成accessToken 3 拿到accessToken之后 尝试使用其中的某一个接口 比如说消息推送 创建模板 生成模板ID 生成之后会产生模板ID 4 根据openID 模
  • 网络通信深入解析:探索TCP/IP模型

    http协议访问web 你知道在我们的网页浏览器的地址当中输入url 未必是如何呈现的吗 web浏览器根据地址栏中指定的url 从web服务器获取文件资源 resource 等信息 从而显示出web页面 web使用HTTP 超文本传输协议
  • linux bitcoin-qt程序运行时 缺少 libboost.so 动态库

    这是因为该程序在系统变量的路径下未找到自己的依赖库 所以就启动不了 执行将缺省的依赖库补上 能让程序搜索的到就可以了 bitcoin可执行程序的运行错误截图 执行打开后发生的错误提示 bitcoin qt home cly project
  • Linux epoll 详解

    最近 异想天开 想用D实现一个web服务器 似乎已经想这件事好久了 只不过之前是C 自然而然得开始研究epoll 早就听说过epoll的大名 只不过网上的教程似乎没多少 并且感觉也没怎么把用法给讲完整 好在 通过几天的学习 也算是有所积累
  • 解决使用InfluxDBClient报错influxdb.exceptions.InfluxDBClientError: 401 unauthorized

    解决方案 查看自己的InfluxDB数据库版本 如果版本是1 8 或是2 x 则 首先卸载influxdb pip uninstall influxdb 然后安装 pip install influxdb client ciso 后续使用i
  • K8S-微服务组件

    微服务组件包括哪些 一个完整的微服务包括的组件 注册中心 配置中心 熔断 限流 链路跟踪 路由 在微服务中 有些组件为必须组件 必须启动存在 客户端才能正常调用 必须组件 注册中心 后台服务 Provider 非必须组件 配置中心 熔断 限
  • select poll epoll

    Select select本质上是通过设置或者检查存放fd标志位的数据结构来进行下一步处理 用Select就可以完成非阻塞 所谓非阻塞方式non block 就是进程或线程执行此函数时不必非要等待事件的发生 select在socket编程中