高级IO-epoll

news2024/11/27 13:39:19

在这里插入图片描述

文章目录

  • 1. I/O多路转接之poll
    • 1.1 代码样例
    • 1.2 poll优缺点
  • 2. I/O多路转接之epoll
    • 2.1 epoll的相关系统调用
  • 3. epoll工作原理
    • 3.1 epoll的优点
  • 4. 代码样例
    • 4.1 初始化服务器
    • 4.2 启动服务器
  • 5. epoll工作方式
  • 6. epoll的使用场景

1. I/O多路转接之poll

poll函数解决了,select函数的服务器的承载数量是有限的和每次进行select调用都要对参数进行重置这两个问题
在这里插入图片描述
timeout表示poll函数的超时时间,单位是毫秒(ms)。

返回结果:
返回值小于0,表示出错。
返回值等于0,表示poll函数等待超时。
返回值大于0,表示poll由于监听的文件描述符就绪而返回

nfds_t其实就是一个整型,表示fds数组的长度,也就是说你想关心的fd有多少个

fds是一个poll函数监听的结构列表,每一个元素中,包含了三部分内容,要监听的文件描述符,用户告诉内核要监听的事件集合,内核告诉用户返回的事件集合

fds结构体后面两个成员变量解决了输入和输出分离问题。

但是还有一个问题:每一个fd,都可能有不同的事件要关心,我们该如何辨别呢
events和revents的取值:
在这里插入图片描述
这些全是宏,每个宏只占1个比特位,当我们进行按位或时,就可以代表各种各样的事件情况。

1.1 代码样例

我们可以对SelectServer进行简单的修改:
在这里插入图片描述
在这里插入图片描述
-1代表的是阻塞状态。
在这里插入图片描述
这里的revents里面如果被设置了POLLIN说明里面的事件就绪了。
在这里插入图片描述
在这里插入图片描述

1.2 poll优缺点

poll的优点
不同与select使用三个位图来表示三个fdset的方式,poll使用一个pollfd的指针实现。pollfd结构包含了要监视的event和发生的event,不再使用select“参数-值”传递的方式,接口使用比select更方便。poll并没有最大数量限制 (但是数量过大后性能也是会下降)

poll的缺点
1.poll中监听的文件描述符数目增多时,和select函数一样,poll返回后,需要轮询pollfd来获取就绪的描述符。
2.每次调用poll都需要把大量的pollfd结构从用户态拷贝到内核中。
3.同时连接的大量客户端在一时刻可能只有很少的处于就绪状态, 因此随着监视的描述符数量的增长,其效率也会线性下降

2. I/O多路转接之epoll

那么介绍了select和poll,多路转接还存在什么问题呢
1.select、poll都是基于多个fd进行遍历检测,来识别事件,链接多的时候,一定会引起遍历周期的增加。
2.对于事件(用户告诉内核,内核通知用户)需要使用的数据结构(数组),需要程序员自己维护

2.1 epoll的相关系统调用

按照man手册的说法: 是为处理大批量句柄而作了改进的poll。epoll 有3个相关的系统调用。但是不论有多少个接口,核心工作就是等。

第一个接口
在这里插入图片描述
创建一个epoll的句柄,自从linux2.6.8之后,size参数是被忽略的,但是必须大于0。用完之后, 必须调用close()关闭

返回值:成功返回一个文件描述符,失败返回-1,并填写错误信息。
这个接口的任务是创建一个epoll模型。

第二个接口
在这里插入图片描述
epoll的事件注册函数,它不同于select()是在监听事件时告诉内核要监听什么类型的事件,而是在这里先注册要监听的事件类型
第一个参数是epoll_create()的返回值(epoll的句柄)

第二个参数表示动作,用三个宏来表示
在这里插入图片描述
第三个参数是需要监听的fd

第四个参数是告诉内核需要监听什么事,也就是用户告诉内核

第三个接口
在这里插入图片描述
收集在epoll监控的事件中已经就绪的事件,也就是等的工作

参数events是分配好的epoll_event结构体数组。epoll将会把发生的事件赋值到events数组中 (events不可以是空指针,内核只负责把数据复制到这个events数组中,不会去帮助我们在用户态中分配内存)

maxevents告之内核这个events有多大,这个 maxevents的值不能大于创建epoll_create()时的size

参数timeout是超时时间 (毫秒,0会立即返回,-1是永久阻塞)

如果函数调用成功,返回对应I/O上已准备好的文件描述符数目,如返回0表示已超时,返回小于0表示函数失败。

下面我们先介绍一下一个结构struct epoll_event
在这里插入图片描述
第一个uint32_t events代表的是事件有没有就绪。其它的我们后面再介绍。

3. epoll工作原理

操作系统如何得知,网络中的数据到来了
网卡先得到数据,会向CPU发送硬件中断,调用OS预设的中断函数,负责从外设进行数据拷贝,从外设拷贝到内核缓冲区中。所以在这个中断函数中,设置了回调函数。

针对特定的一个或者多个fd,设定对应的回调机制,当fd缓冲区中有数据的时候,就进行回调

当我们调用epoll_create方法时,会给我们创建一颗红黑树,红黑树的节点上存储了用户想关心哪一个文件描述符上面的什么事件。并且也会创建一个就绪队列,队列的节点存储了,红黑树中哪些fd的事件已经就绪了。

所以,回调函数帮我们做了4件事:
1.获取就绪的fd。2.获取就绪的事件是什么。3.构建queue_node节点。4.将节点链接进入就绪队列

所以,回调机制、红黑树、就绪队列统称为epoll模型。epoll_create函数就是创建这个模型,epoll_ctl操作的就是这颗红黑树的增加,查询,删除。epoll_wait就是等就绪队列里面有没有数据,有数据就直接拿到应用层,所以它的时间复杂度是O(1)。

epoll为什么高效
因为设置了回调机制,当底层有数据了,通过回调的机制获取就绪的文件描述符,获取就绪事件,构建节点到就绪队列中,这个工作由回调函数自动完成。

3.1 epoll的优点

1.接口使用方便:虽然拆分成了三个函数,但是反而使用起来更方便高效。不需要每次循环都设置关注的文件描述符,也做到了输入输出参数分离开。

2.数据拷贝轻量:只在合适的时候调用 EPOLL_CTL_ADD 将文件描述符结构拷贝到内核中,这个操作并不频繁(而select/poll都是每次循环都要进行拷贝)。

3.事件回调机制:避免使用遍历,而是使用回调函数的方式,将就绪的文件描述符结构加入到就绪队列中,epoll_wait 返回直接访问就绪队列就知道哪些文件描述符就绪。这个操作时间复杂度O(1)。即使文件描述符数目很多,效率也不会受到影响。

4.没有数量限制:文件描述符数目无上限。

4. 代码样例

在这里插入图片描述
这是epoll服务器的基本成员函数以及构造和析构。

4.1 初始化服务器

在这里插入图片描述
日志是之前写过的。

4.2 启动服务器

那么第一步肯定要把我们的监听套接字添加到epoll模型中:
在这里插入图片描述
在填写最后一个参数的时候,我们该如何填写参数呢?
在这里插入图片描述
第一个成员变量我们有对应的宏:
在这里插入图片描述
第二个我们先把fd添加上,其余的后面再说。

当我们添加监听套接字进入红黑树中后,我们就可以等就绪队列有数据了。
在这里插入图片描述
在这里插入图片描述
epoll_wait的返回值是就绪的fd的个数,当n大于0时,说明有就绪事件产生了,我们需要去处理。因为我们把只要就绪的事件存放到revs,那么我们就不需要传num,一个一个去遍历判断,因为里面全是就绪的。
在这里插入图片描述
在这里插入图片描述
我们这里只关心读事件,其它事件后面写完整版再说。那么读事件就分监听套接字和普通套接字两种。
在这里插入图片描述
当我们监听成功获得新链接时,我们就把新链接的套接字托管给epoll模型。

那么对于普通套接字的处理,我们可以采用回调方法来处理:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这样我们可以自己设置读取数据函数。但是这里还是有一个bug,我们怎么知道recv读取的报文是完整的呢?
在这里插入图片描述
然后我们再对处理的返回值进行判断。如果出错了,就在红黑树中把这个节点删除,并且关闭此文件描述符。

5. epoll工作方式

epoll有2种工作方式-水平触发(LT)和边缘触发(ET)
在这里插入图片描述
LT:只要底层有数据,就会一直通知你,这也是多路转接的默认模式,可以让程序员在上层编码的时候,可以暂时不把数据读取完毕,不用担心底层不通知你进而导致数据丢失的问题

ET:只要底层数据,从无到有,从有到多,变化的时候才会通知你,倒逼程序员一旦收到通知,就必须将自己收到的数据从内核中全部读取完成,否则可能会有数据丢失的风险

LT和ET谁更高效
按机制来说,ET比较高效,但是LT也可以设置一次性读完,这种机制本质上:让上层尽快取走数据的一种机制,让TCP有更大的窗口。

必须要内核数据一次性读完,我们怎么知道呢
必须循环read/recv进行读取,当出错或者读完才能结束知道。但是如果fd是阻塞式的,那么最后一次读取,就势必会导致read/recv阻塞。所以,我们必须让ET模式下,所以的fd,sock必须是非阻塞的。

select和poll其实也是工作在LT模式下。epoll既可以支持LT,也可以支持ET。

6. epoll的使用场景

epoll的高性能, 是有一定的特定场景的,如果场景选择的不适宜,epoll的性能可能适得其反。

对于多连接,且多连接中只有一部分连接比较活跃时,比较适合使用epoll

例如:典型的一个需要处理上万个客户端的服务器,例如,各种互联网APP的入口服务器,这样的服务器就很适合epoll。如果只是系统内部,服务器和服务器之间进行通信,只有少数的几个连接,这种情况下用epoll就并不合适,具体要根据需求和场景特点来决定使用哪种IO模型。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1008781.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

delphi 自带的dbgrid表格控件增加下选框

在表格里用combobox很正常 自带的dbgrid加也很方便,环境是xe10 procedure TfrmBaseInfo.LoadDesk; varssql: string;i: Integer;column: TColumn; beginssql : select * from desk_info ;qry_desk.Connection : dmMain.FDConnection1;qry_desk.Close;qry_desk.S…

机器视觉之Basler工业相机使用和配置方法(C++)

basler工业相机做双目视觉用,出现很多问题记录一下: 首先是多看手册:https://zh.docs.baslerweb.com/software 手册内有所有的源码和参考示例,实际上在使用过程中,大部分都是这些源码,具体项目选择对应的…

java实现克里金插值导出geojson矢量数据(kriging)

生成效果 在现代科学研究中,数据的处理和分析是至关重要的一环。然而,我们往往会遇到数据缺失的情况,这时就需要使用插值方法来填补这些缺失值。其中,克里金插值法是一种常用的方法,在很多领域都有广泛的应用。 首先&…

RK3568开发笔记(九):开发板buildroot固件调通RS485口,运行项目中RS485协议调试工具Demo

若该文为原创文章,转载请注明原文出处 本文章博客地址:https://hpzwl.blog.csdn.net/article/details/132869448 红胖子网络科技博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬…

【剑指Offer】52.两个链表的第一个公共节点

题目 输入两个链表,找出它们的第一个公共节点。 如下面的两个链表: 在节点 c1 开始相交。 示例 1: 输入:intersectVal 8, listA [4,1,8,4,5], listB [5,0,1,8,4,5], skipA 2, skipB 3 输出:Reference of the n…

【Linux】网络编程套接字(C++)

目录 一、预备知识 【1.1】理解源IP地址和目的IP地址 【1.2】认识端口号 【1.3】理解 "端口号" 和 "进程ID" 【1.4】理解源端口号和目的端口号 【1.5】认识TCP协议 【1.6】认识UDP协议 二、网络字节序 【2.1】socket编程接口 【2.1.1】socket AP…

5款实用的Redis可视化工具

Redis可视化工具是一种用于管理和监视Redis数据库的工具,它提供了一个可视化界面来操作和查看Redis的数据和配置信息, 可以让我们更加直观地管理和操作Redis数据库。下面介绍四款比较不错的Redis可视化工具。 1.Redis可视化工具推荐—RedisInsight Red…

美创科技入选第二届安徽省网络和数据安全应急技术支撑单位

9月11日,2023年安徽省网络安全宣传周活动在阜阳市正式启动。安徽省委常委、宣传部部长陈舜出席并宣布网安周正式启动。阜阳市委书记刘玉杰、省委宣传部副部长、省委网信办主任张杰华出席并致辞。 开幕式上,省委网信办副主任齐海洋发布第二届安徽省网络和…

Template serialization - shared_ptr<class T>

下面包含的所有代码片段都在 boost::serialization 命名空间内定义。 shared_ptr < T > 在 shared_ptr.hpp 中定义。 shared_ptr 的一般类轮廓如下&#xff1a; shared_ptr 包括以下成员&#xff1a; T *px;shared_count pn;&#xff0c;其中包含指向&#xff1a; sp_c…

(二十七)大数据实战——hbase高可用集群安装与部署

前言 本节内容我们主要介绍HBase高可用集群的安装部署。HBase是一个开源的分布式非关系型数据库管理系统&#xff08;NoSQL&#xff09;&#xff0c;它运行在Apache Hadoop之上。它基于Google的Bigtable论文设计&#xff0c;并且具有高扩展性、高可靠性和高性能的特点。HBase通…

Python 04 之变量【列表,元组,集合,字典,字符串】

&#x1f600;前言 在Python编程语言中&#xff0c;我们经常会遇到各种数据类型和相应的操作方法。理解和掌握这些基本构造是进行有效编程的前提。在本文中&#xff0c;我们将介绍两种非常重要的数据结构 - 集合和字典&#xff0c;然后我们将深入探讨字符串及其相关的操作和处理…

父域 Cookie实现sso单点登录

单点登录&#xff08;Single Sign On, SSO&#xff09;是指在同一帐号平台下的多个应用系统中&#xff0c;用户只需登录一次&#xff0c;即可访问所有相互信任的应用系统。Cookie 的作用域由 domain 属性和 path 属性共同决定。在 Tomcat 中&#xff0c;domain 属性默认为当前域…

CUDA小白 - NPP(8) 图像处理 Morphological Operations

cuda小白 原始API链接 NPP GPU架构近些年也有不少的变化&#xff0c;具体的可以参考别的博主的介绍&#xff0c;都比较详细。还有一些cuda中的专有名词的含义&#xff0c;可以参考《详解CUDA的Context、Stream、Warp、SM、SP、Kernel、Block、Grid》 常见的NppStatus&#xf…

消除笔哪个P图软件有?这几种软件都有消除笔功能

哪些软件中有消除笔工具呢&#xff1f;我们在日常的生活中&#xff0c;会经常有编辑图片的需求&#xff0c;如果图片上有一些内容我们想要将它去除掉&#xff0c;如文字、涂鸦、笔记、标记等&#xff0c;需要用到一些消除笔工具&#xff0c;那么哪些软件具有这个功能并且还非常…

Excel变天了!国内已经可以用Python了!看看如何操作

对于大部分学python的同学来说&#xff0c;绝大部分场景都是用Pandas处理excel。 但有时简单的处理还要打开Jupyter或者VS Code&#xff0c;就有点麻烦。 现在&#xff01;微软已经把Python塞到Excel里啦&#xff01; 其实之前就已经塞了&#xff0c;但这几天国内都可以用了。…

传猪场员工因抑郁症去世,ACM金牌

前言 一位素未蒙面的学弟&#xff0c;R.I.P 既然是 “传”&#xff0c;我们就不能假定人家有抑郁症&#xff0c;其实前天就收到了这个消息&#xff0c;因为是一个学校的&#xff0c;又是ACM金牌&#xff0c;所以第一时间就在群里刷屏了&#xff0c;这件事情对于一个家庭来说&am…

10个TikTok影响力营销策略,让你的品牌崭露头角

TikTok已经成为一种崭露头角和塑造品牌声誉的强大平台。随着数以亿计的用户在这个短视频应用上分享创意和内容&#xff0c;品牌和营销专业人士也越来越多地将其作为推广产品和服务的渠道。 在本文中&#xff0c;我们将探讨10个TikTok影响力营销策略&#xff0c;帮助你的品牌在…

【Spring Boot】有这一文就够了

作者简介 前言 作者之前写过一个Spring Boot的系列&#xff0c;包含自动装配原理、MVC、安全、监控、集成数据库、集成Redis、日志、定时任务、异步任务等内容&#xff0c;本文将会一文拉通来总结这所有内容&#xff0c;不骗人&#xff0c;一文快速入门Spring Boot。 专栏地址…

了解CRM软件系统三种类型的特点与区别

市面上的CRM系统大致可以分为三种主要类型&#xff1a;分析型CRM、运营型CRM和协作型CRM。很多人对这三种类型的CRM系统不太了解&#xff0c;不知道该如何区分&#xff0c;下面我们就来说说CRM系统的3种类型&#xff1a;分析型、运营型和协作型的区别。 分析型CRM的特点&#…

系统灰度随笔记

系统灰度随笔记 这段时间系统重构&#xff0c;负责重构的其中一个模块需要与四个上游系统对接进行切换&#xff0c;虽然自己在这个过程中也设计了一套灰度方案来承接&#xff0c;将灰度的主动权控制在下游&#xff0c;但是很难同时应对四个上游系统&#xff0c;因为每个上游系…