嵌入式学习----IO多路复用

news2024/9/20 14:54:16

1.概念:多个IO复用一个进程

2.IO多路复用的一般实现:

(1)创建文件描述符集合

(2)添加文件描述符到集合中

(3)通知内核开始监测

(4)根据返回的结果做对应的操作(对io读、写操作)

3.应用场景:
    1. 构建并发服务器,使用IO多路复用监测多个客户端套接字
    2. 使用io多路复用监测多个IO所对应的通信(如:网络、串口、can..)
    3. 在阻塞io中,进行超时监测

4.IO多路复用的分类:

select,poll,epoll

IO多路复用技术(select函数模型和poll函数模型):进程通过告诉多路复用器(内核)(也就是select函数和poll函数)所有的socket号,多路复用器再去获取每一个socket的状态,当程序获取到某个socket号有事件发生了,则去该socket号上进行处理对应的事件,read事件或者是recived事件。(补充select函数与poll函数的区别是,前者底层是数组,所以有最大连接数的限制,后者是链表,无最大连接数的限制)
缺点:①同样与NIO相同,需要遍历所有socket,O(N)复杂度。②重复传递数据。因为内核是无状态的,每次都要根据进程不断重复从用户态向内核态传递所有的socket号去遍历每一个socket,获取它们的状态。浪费资源与效率,可以使用一个记事本记录每个socket的监听事件。

IO多路复用技术(epoll函数模型):epoll函数模型主要是调用了三个函数:epoll_create() , epoll_ctl() , epoll_wait();
底层流程:①通过epoll_create() 函数创建一个文件,返回一个文件描述符(Linus系统一切对象皆为文件)fd ② 创建socket接口号4,绑定socket号与端口号,监听事件,标记为非阻塞。通过epoll_ctl() 函数将该socket号 以及 需要监听的事件(如listen事件)写入fd中。③循环调用epoll_wait() 函数进行监听,返回已经就绪事件序列的长度(返回0则说明无状态,大于0则说明有n个事件已就绪)。例如如果有客户端进行连接,则,再调用accept()函数与4号socket进行连接,连接后返回一个新的socket号,且需要监听读事件,则再通过epoll_ctl()将新的socket号以及对应的事件(如read读事件)写入fd中,epoll_wait()进行监听。循环往复。
优点:不需要再遍历所有的socket号来获取每一个socket的状态,只需要管理活跃的连接。即监听在通过epoll_create()创建的文件中注册的socket号以及对应的事件。只有产生就绪事件,才会处理,所以操作都是有效的,为O(1).
补充:众所周知,设备(进程)是通过中断机制来请求CPU进行IO处理。使用epoll模型能加快CPU的处理效率。如网卡想通过IO来向系统传输一个数据,就通过中断获取CPU时间片,将该数据放置就绪事件序列中,等待CPU下一次进行epoll_wait()即可获取到对应数据,无需再通过往fd中注册socket号对应的事件等等。

epoll函数的边缘触发与水平触发的区别:
边缘触发:当文件描述符关联的读内核缓冲区发生变化时候,才发出可读信号进行通知
水平触发:只要文件描述符关联的读内核缓冲区非空,有数据可以读取,就一直发出可读信号进行通知

example:
1.读缓冲区刚开始是空的
2.读缓冲区写入2KB数据
3.水平触发和边缘触发模式此时都会发出可读信号
4.收到信号通知后,读取了1kb的数据,读缓冲区还剩余1KB数据
5.水平触发会再次进行通知,而边缘触发不会再进行通知

因为边缘触发对于一次就绪事件只会触发一次,所以需要一次性的把缓冲区的数据读完为止,也就是一直读,直到读到缓冲区为空为止,因为这一点,边缘触发需要设置文件句柄为非阻塞

epoll底层

select实现io复用的函数原型:

 int select(int nfds, fd_set *readfds, fd_set *writefds,
                  fd_set *exceptfds, struct timeval *timeout);
       功能:监测多路IO
       参数:
                 nfds : 关注的文件描述符中的最大值+1   
                  readfds:关注的读事件的文件描述符集合
                 writefds:关注的写事件的文件描述符结合
                 exceptfds:其他  异常
                 timeout : 超时时间,如果不设置:NULL
      返回值:
              成功:返回到达事件的个数
               失败:-1
              设置了超时时间:超时时间到达但没有事件,返回0
                     

       void FD_CLR(int fd, fd_set *set);
       int  FD_ISSET(int fd, fd_set *set);
       void FD_SET(int fd, fd_set *set);
       void FD_ZERO(fd_set *set);

epoll函数原型:

int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
参数:
          epfd:文件描述符集合句柄
          op: 
                   EPOLL_CTL_ADD: 向集合中添加文件描述符
                   EPOLL_CTL_MOD: 修改集合
                   EPOLL_CTL_DEL :删除文件描述符
          
          fd :操作的文件描述符
         event :文件描述符所对应的事件


          typedef union epoll_data {
               void        *ptr;
               int          fd;
               uint32_t     u32;
               uint64_t     u64;
           } epoll_data_t;

           struct epoll_event {
               uint32_t     events;      /* Epoll events */
               epoll_data_t data;        /* User data variable */
           };

          event : EPOLLIN :  读操作
                       EPOLLOUT : 写事件


    int epoll_wait(int epfd, struct epoll_event *events,
                      int maxevents, int timeout);
   功能:监测IO事件
   参数:
             epfd : 文件描述符集合句柄
             events : 保存到达事件的结合的首地址
             maxevents : 监测时事件的个数
            timeout:超时时间
                           -1  :不设置超时时间

返回值:
          成功:返回到达事件的个数
          失败:-1
          设置超时:超时时间到达返回0
 

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

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

相关文章

TESSY创建单元测试或集成测试工程

我们以tessy5.1 IDE为例,给大家展示工程的创建过程。 1、打开TESSY5.1软件后,会弹出: 2、点击NEW Project后,会弹出: 3、接下来,就可以打开刚创建的工程: 4、进入到TESSY的主界面后&#xff0c…

清凉行动启航!汕头电信爱心翼站夏送清凉,每一份汗水都值得被温柔以待

8月中旬汕头电信濠江营业厅开展了“与你一起,清凉一夏”爱心翼站•夏送清凉活动。 在温馨的活动氛围中,爱心翼站的爱心大使与志愿者们,以生动有趣的小课堂,为小朋友们揭开了中暑这一话题的神秘面纱,细致阐述了其定义及…

在团队里对着干的人

在团队里对着干的人,踢走; 在团队里跟着干的人,培养; 在团队里帮着干的人,分钱; 在团队里领着干的人,分红。 这是规律也是规矩,一个真正的强者,是看他帮助了多少人&#…

CLIP微调方法总结

文章目录 前言1️⃣ Tip-Adapter论文和源码原理介绍 2️⃣Cross-modal Adaptation(跨模态适应)论文和源码原理介绍 3️⃣ FD-Align(Feature Discrimination Alignment,特征判别对齐)论文和源码原理介绍 总结 前言 本文…

教您用军团要塞2服务器开服联机教程

1、购买后登录服务器 进入控制面板后会出现正在安装的界面 2、下载连接工具 打开Steam库中搜索Source SDK Base 2013 Multiplayer并安装 3、下载游戏 以下三个链接均为同一个游戏 百度 通过百度网盘分享的文件:tf2classic.zip 链接:百度网盘 请输入提…

(最新)华为 2024 届秋招-硬件技术工程师-单板硬件开发—机试题—(共12套)(每套四十题)

(最新)华为 2024 届秋招-硬件技术工程师-单板硬件开发—机试题—(共12套)(每套四十题) 岗位——硬件技术工程师 岗位意向——单板硬件开发 真题题目分享,完整版带答案(有答案和解析&#xff0…

浅析WebRTC技术在智慧园区视频管理场景中的应用

随着科技的飞速发展,智慧园区作为城市智慧化的重要组成部分,正逐步成为现代化管理的重要方向。智慧园区的建设不仅涉及硬件设施的智能化升级,还离不开高效的视频管理和实时通信技术。在这一背景下,WebRTC(Web Real-Tim…

BackdoorLLM:一个针对生成性LLMs后门攻击的全面基准测试

大型语言模型(LLMs)在从自然语言理解到机器翻译等一系列任务上取得了显著的突破性进展。例如,GPT-4模型展示了在生成类人文本和解决复杂问题方面的前所未有的能力。然而,近期的研究表明,LLMs存在一个关键的脆弱性&…

sqli-labs靶场通关攻略(41-45关)

第41关 这关我们使用工具sqlmap练习一下(这里如果用本机的回环地址访问靶场的话只能在你的本机访问,因为我们是在虚拟机上进行扫描,所以不能使用127.0.0.1访问) 进入虚拟机kali,打开终端 查库 sqlmap -u 网址 -- curr…

uniapp生活记账小程序

Springboot vue uniapp生活记账小程序,前端采用vue uni-app设计开发,后端采用 Springboot 开发前端对应的数据接口,首页显示生活账单信息,我的野蛮统计记账信息和微信登录状况。记账页面可以,根据不同类别的日常消费记…

MySQL集群技术4——MySQL路由

mysql-route MySQL 路由(Routing)通常指的是在 MySQL 架构中如何处理客户端请求和数据流向的问题。在 MySQL 中,路由可以涉及多种不同的场景和技术,包括但不限于反向代理、负载均衡、读写分离等。下面我将详细介绍这些场景和技术…

如何反射获取类的全部信息?(java代码)

什么是反射? 反射是 Java 提供的一种机制,允许在运行时动态地获取类的信息(如类的名称、方法、字段等),以及创建对象和调用方法。反射利用了 java.lang.reflect 包中的类,如 Class、Method、Field 和 Cons…

仿BOSS招聘系统开发:构建高效、智能的在线招聘平台

在数字化时代,招聘行业正经历着前所未有的变革。BOSS直聘作为国内领先的招聘平台,以其高效的匹配机制、丰富的职位信息和便捷的用户体验,赢得了广泛的市场认可。本文将探讨如何开发一个仿照BOSS招聘系统的在线招聘平台,旨在为企业…

8月28复盘日记

8月28复盘日记 前言今日感恩今日知识今日反思今日名言 前言 今天早上是六点半起床嘻嘻,这两天因为生理期,皮质醇似乎有些高,入睡会有些困难。但是因为今天是开学第一天,意味着,健身房恢复晨练了!我可太喜欢晨练时间安安静静的健身…

怎么又快又好制作流程图?试试这2款流程图制作神器,专业!

推荐2款简单好用的流程图制作软件,帮你轻松搞定各种流程图。 1、GitMind 点点击链接直达官网>>gitmind.cn GitMind是一个在线流程图制作工具,模板类型全,支持免费下载,由国内团队研发,操作简单,使用…

功率器件和滤波器件的选型及测试方法

目录 一、功率器件的选型及测试方法 1.1功率器件的选型 1.2功率器件的测试方法 二、滤波器件的选型及测试方法 2.1滤波器件的选型 2.2滤波器件的测试方法 三、表格总结 一、功率器件的选型及测试方法 1.1功率器件的选型 在电子电路设计中,功率器件的选择是…

c++异常处理(c++11版)与智能指针 SmartPtr 的应用(主讲shared_ptr浅实现)

引子:找C语言的异常时,你是否会被奇怪的错误码或程序终止报错而感到无奈,对找不到错误在哪的心烦?在害怕内存泄漏时,你是否每一步,每一句代码都要仔细分析,在用完之后进行资源空间的释放&#x…

用powermock编写单元测试

1、pom文件引入jar包 <!-- 单元测试 start --> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope> </dependency> <dependency>&…

Jenkins服务安装配置

什么是 Jenkins Jenkins 是一个开源的自动化服务器&#xff0c;主要用于持续集成&#xff08;CI&#xff0c;Continuous Integration&#xff09;和持续交付/持续部署&#xff08;CD/CD&#xff0c;Continuous Delivery/Continuous Deployment&#xff09;。它帮助开发团队自动…

48.【C语言】结构体补充

承接20.【C语言】初识结构体&#xff08;重要&#xff09;中的结构体成员的访问 目录&#xff1a; 1.结构体创建 2.利用函数控制结构体 3.使用“结构体指针变量-->结构体成员变量”来修改结构体的数据 4.传值还是传址&#xff1f; 1.结构体创建 依据第20篇&#xff0c;可以…