嵌入式学习笔记——day36-多路IO复用

一、基本概念

(服务器多客户端模型)

定义:

        单线程或单进程同时监测若干个文件描述符是否可以执行IO操作的能力

作用:

        应用程序通常需要处理来自多条事件流中的事件,比如我现在用的电脑,需要同时处理键盘鼠标的输入、中断信号等等事件,再比如web服务器如nginx,需要同时处理来来自N个客户端的事件。

        逻辑控制流在时间上的重叠叫做 并发(时间段是并行,但时间点上是串行的)

并行:

        在一个时间点上同时运行。
    
        而CPU单核在同一时刻只能做一件事情,一种解决办法是对CPU进行时分复用(多个事件流将CPU切割成多个时间片,不同事件流的时间片交替进行)。在计算机系统中,我们用线程或者进程来表示一条执行流,通过不同的线程或进程在操作系统内部的调度,来做到对CPU处理的时分复用。这样多个事件流就可以并发进行,不需要一个等待另一个太久,在用户看起来他们似乎就是并行在做一样。

使用并发处理的成本:
        线程/进程创建成本
        CPU切换不同线程/进程成本 Context Switch        

      (上下文切换:页表、寄存器、缓存)
         多线程的资源竞争

       

有没有一种可以在单线程/进程中处理多个事件流的方法呢?一种答案就是IO多路复用。

因此IO多路复用解决的本质问题是在用更少的资源完成更多的事。

二、IO模型 

1、阻塞IO  
2、非阻塞IO  EAGAIN  忙等待 errno
3、信号驱动IO  SIGIO 用的相对少(了解)
4、并行模型 进程,线程 

2.1阻塞IO 

最常用 默认设置

 

2.2非阻塞IO 

在阻塞IO的基础上调整其为不再阻塞等待。
     在程序执行阶段调整文件的执行方式为非阻塞:
            ===》fcntl() ===>动态调整文件的阻塞属性 

int fcntl(int fd,         int cmd,         ... /* arg */ );操作对象    进行何种操作        看第二个参数是否需要

   功能:修改指定文件的属性信息。
    参数:fd 要调整的文件描述符
          cmd 要调整的文件属性宏名称
          ... 可变长的属性值参数。
    返回值:成功  不一定,看cmd; 失败  -1

1.获得原设备状态标志位

2.在原标志位基础上加上 非阻塞

3.当是FILE *文件时,使用fileno,转换为标志位

4.当写0,是只读

eg:修改文件的非阻塞属性:
        int flag ;
        flag  = fcntl(fd,F_GETFL,0);  ///获取fd文件的默认属性到flag变量中。
        flag  = flag | O_NONBLOCK;    ///将变量的值调整并添加非阻塞属性
        fcntl(fd,F_SETFL,flag);       ///将新属性flag设置到fd对应的文件生效。

        以上代码执行后的阻塞IO将变成非阻塞方式。

缺点:CPU占用率高  

2.3信号驱动IO(了解) 

文件描述符需要追加 O_ASYNC//信号通知 标志。
    设备有io事件可以执行时,内核发送SIGIO信号。
    
        1.追加标志
        int flag ;
        flag  = fcntl(fd,F_GETFL,0);
        fcntl(fd,F_SETFL,flag | O_ASYNC);    //设置为异步
        2.设置信号接收者
        fcntl(fd,F_SETOWN,getpid());//常用设置
        3.对信号进行捕获
        signal(SIGIO,myhandle);

2.4并行模型 

 1.进程
        2.线程
 IO 多路复用 ===》并发服务器 ===》TCP协议    
        3、select循环服务器 ===> 用select函数来动态检测有数据流动的文件描述符 

2.5 IO多路复用

2.5.1 select函数

select:

 

  1. 创建fd集合
  2. 文件描述符加入集合
  3. select等待事件到来
  4. 找到对应的fd,进行读写操作
  5. 清除标志位
int select(int nfds, fd_set *readfds, fd_set *writefds,检测读            一般不检测fd_set *exceptfds,错误struct timeval *timeout);超时控制,NULL为阻塞,填秒数/毫秒,都写0,非阻塞工作,只扫一圈,都没有准备好,返-1;

功能:完成指定描述符集合中有效描述符的动态检测。
          该函数具有阻塞等待功能,在函数执行完毕后
          目标测试集合中将只保留最后有数据的描述符。

    参数:nfds 描述符的上限值,一般是链接后描述符的最大值+1;
               readfds 只读描述符集
               writefds 只写描述符集
               exceptfds 异常描述符集
               以上三个参数都是 fd_set * 的描述符集合类型
               timeout  检测超时 如果是NULL表示一直检测不超时 。

    返回值:超时 0
                  失败  -1
                  成功 >0

为了配合select函数执行,有如下宏函数:
        void FD_CLR(int fd, fd_set *set);
        功能:将指定的set集合中编号为fd的描述符号删除。

        int  FD_ISSET(int fd, fd_set *set);//是否就绪
        功能:判断值为fd的描述符是否在set集合中,
              如果在则返回真,否则返回假。

        void FD_SET(int fd, fd_set *set);
        功能:将指定的fd描述符,添加到set集合中。

        void FD_ZERO(fd_set *set);
        功能:将指定的set集合中所有描述符删除。 

 

2.5.2 epoll函数 

epoll:

 

创建fd集合(二叉树)
加入关心的文件描述符
epoll_wait                 当 epoll_wait 成功时,它返回准备就绪的文件描述符的数量,如果超时则返回 0。如果发生错误,则返回 -1 并设置相应的 errno。
epoll把准备就绪的fd放入rev集合(数组)

1.int epoll_create(int size);

2.int epoll_ctl(int epfd,       int op,         int fd,         struct epoll_event *event);

                        哪个集合   何种操作           放入谁        监视事件,用户自定义变量

3.int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout);

                                                                                                                 -1 

                                                                                                                 0 非阻塞

epoll 解决了select和poll的几个性能上的缺陷:

①不限制监听的描述符个数(poll也是),只受进程打开描述符总数的限制;

②监听性能不随着监听描述 符数的增加而增加,是O(1)的,不再是轮询描述符来探测事件,而是由描述符主动上报事件;

③使用共享内存的方式,不在用户和内核之间反复传递监听的描述 符信息;

④返回参数中就是触发事件的列表,不用再遍历输入事件表查询各个事件是否被触发。
epoll显著提高性能的前提是:监听大量描述符,并且每次触发事件的描述符文件非常少。
epoll的另外区别是:①epoll创建了描述符,记得close;

                                 ②支持水平触发和边沿触发。

 仅TCP使用(由对方的通信套接字)

getpeername函数是一个网络编程中常用的函数,它用于获取与某个套接字关联的远程协议地址。这个函数在网络通信中非常有用,尤其是在需要获取连接对方的IP地址和端口号时。

int getpeername(int sockfd, struct sockaddr *peeraddr, socklen_t *addrlen);

sockfd 是需要获取远程协议地址的套接字描述符。

peeraddr 是一个指向struct sockaddr结构的指针,该结构将被填充远程地址信息。

addrlen 是一个指向socklen_t类型的变量,初始时表示peeraddr指向的缓冲区的大小,函数返回时,它包含远程地址的实际大小。

getpeername(conn,(SA),&cli,&len);

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

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

相关文章

微服务数据一致性技术解析:从单体到微服务的数据困局

关键词: 微服务数据一致性, 企业应用, 技术架构, 最佳实践 本文基于多位资深架构师在大型互联网公司的实战经验总结,希望能为正在进行微服务改造的团队提供有价值的参考。如果您在实践中遇到问题,欢迎交流讨论! 目录 一、引言:从…

华为云Flexus+DeepSeek征文 | 基于华为云ModelArts Studio搭建Chatbox AI聊天助手

华为云FlexusDeepSeek征文 | 基于华为云ModelArts Studio搭建Chatbox AI聊天助手 引言一、ModelArts Studio平台介绍华为云ModelArts Studio简介ModelArts Studio主要特点 二、Chatbox介绍Chatbox简介主要特点 三、安装Chatbox应用下载Chatbox软件安装Chatbox工具 四、开通Deep…

基于cpolar的GPT-SoVITS远程访问实践过程

文章目录 前言1.GPT-SoVITS V2下载2.本地运行GPT-SoVITS V23.简单使用演示4.安装内网穿透工具4.1 创建远程连接公网地址 5. 固定远程访问公网地址 前言 在人工智能技术持续革新之际,语音合成领域涌现出突破性进展。由开发者团队"花儿不哭"研发的GPT-SoVI…

Redis数据结构之HyperLogLog

本文作者没有设置VIP可见,并首发在我的博客:https://blog.liuzijian.com/post/redis-data-structure-hyperloglog.html 目录 1.概述2.常用命令2.1 添加元素2.2 返回基数估算值2.3 合并hyperloglog 3.总结 1.概述 基数统计是一种去重复统计功能的基数估计…

django调用 paramiko powershell 获取cpu 核数

在 Django 应用中使用 paramiko 库通过 SSH 连接到远程服务器并执行命令(例如获取 CPU 核数)是一个常见的需求。下面是一个如何实现这一过程的步骤指南: 步骤 1: 安装必要的库 首先,确保你的 Django 项目中安装了 paramiko 库。如…

08-Python文件处理

08-Python文件处理 一、打开关闭文件 可以用 file 对象做大部分的文件操作。 file()在python3中已经被废除,使用open()打开文件 open 函数 先用open()打开一个文件,创建一个file 对象,再用相关方法才可以调用它进行读写。 语法 file ob…

增强现实—Multimodal text style transfer for outdoor vision-and-language navigation

🌟🌟 欢迎来到我的技术小筑,一个专为技术探索者打造的交流空间。在这里,我们不仅分享代码的智慧,还探讨技术的深度与广度。无论您是资深开发者还是技术新手,这里都有一片属于您的天空。让我们在知识的海洋中…

黑马程序员新版Linux学习笔记——第二部分 基础命令

一、Linux目录结构 二、命令基础 三、ls 列目录内容 3.1 命令 3.2 参数 3.3 总结 四、cd 切换工作目录 4.1命令 五、pwd 查看当前工作目录 5.1命令 六、相对路径、绝对路径、特殊路径符 七、mkdir 创建目录命令 7.1命令 八、touch、cat、more 文件操作命令 8.1 touch 8.2c…

日常运维问题汇总-25

76.销售订单交货单状态更新 实务中偶有发生交货已完成,无需开票或开票已经完成,交货单状态为:处理中,且仍然出现在VF04中,如下图所示: 解决方法: T-CODE:VL_COMPLETE,可对错误的DN状态进行更新…

【2025 年】软件体系结构考试试卷-期末考试

2025 年软件体系结构考试试卷 考试学期:2025 考试形式:闭卷 考试时间:120 分钟 年级:______ 专业:软件工程 班级:______ 一、单选题(每小题 1.5 分,共 24 分) 关于策略…

4.查看、删除数据库

1.显示所有数据库 SHOW DATABASE 2.显示数据库创建语句 SHOW CREAT DATABASE db_name 例如想查看某个数据库是怎样创建的,用的什么字符集啥的。 3.数据库删除语句【慎用】 DROP DATABASE [IF EXISTS] db_name 删除某个数据库之前一定要确定是否进行了备份。

设计模式 - 原型模式

原型模式(Prototype),在制造业种通常是指大批量生产开始之前研发出的概念模型,并基于各种参数指标对其进行检验,效果达到了质量要求,即可参照这个原型进行批量生产。即,原型模式可以用对象创建对…

MySQL数据库基础:从零开始的第一步【Linux】

前言 各位小伙伴们,好久不见!近期,我的文章更新频率确实有些缓慢,在此诚挚地向大家道歉。这个月是我的期末考试月,正处于紧张的复习(也可以说是重新学习)阶段。尽管学业繁忙,但我依然…

502 Bad Gateway:服务器作为网关或代理时收到无效响应处理方式

502 Bad Gateway 错误是 Web 开发和服务器管理中常见的问题,通常表示网关或代理服务器收到无效响应。这种错误可能由多种原因引起,包括后端服务故障、网络问题或配置错误等。了解502错误的原因及其处理方式,对于维护网站的可用性和用户体验至…

Abel 变换,离散型分部积分

文章目录 零、引入:分部积分一、Abel 变换1.1 Abel 变换1.2 证明 二、一些比较浅显的应用2.1 等差 乘 等比型求和2.2 平方求和公式2.3 不等式证明 三、一些算法题的式子优化3.1 3500.将数组分割为子数组的最小代价3.2 D. Array Splitting3.3 300. 任务安排1 零、引入…

火山 RTC 引擎12----合流转推 集成

一、火山、网易 合流转推集成 1、 首次先要startPush,要不然,推不了流 void NRTCEngine::PushToCDN(std::string taskID, std::string url) {if (m_video == nullptr) return;bytertc::IMixedStreamConfig* config = getMixedStreamConfig(url);int ret = m_video->star…

基于STM32设计的物联网疫苗冷链物流监测系统

文章目录 一、前言1.1 项目介绍【1】项目开发背景【2】设计实现的功能【3】项目硬件模块组成【4】设计意义【5】国内外研究现状(1)国内研究现状(2)国外研究现状(3)技术演进趋势分析(4)现存技术缺口(5)关键案例技术对比表【6】摘要1.2 设计思路1.3 系统功能总结1.4 开…

音频中采样率和帧是什么?怎么理解?

视频中的“帧”是指一张图片,那么在音频中,“帧”的含义就完全不同了。理解音频中的“帧”概念,对做音视频处理、流媒体开发非常关键。 一、声音是怎么采集的? 音频采集是指通过麦克风等设备捕捉周围环境中的声波,并…

第三方检测护航软件登记:企业合规的技术通行证与市场信任基石

一、软件产品登记测试:合规化的必经之路 根据《软件产品管理办法》,所有上市软件必须通过第三方检测机构的专业评估,确保功能、性能、安全性等指标符合国家标准(如GB/T 25000系列)。这一强制性要求不仅规避了法律风险…

产品页不被收录的6个技术原因(非重复内容/爬虫限制类)

页面未被收录的原因可能藏在代码架构或服务器配置中 比如爬虫无法“看懂”你的动态内容,或是某个参数设置错误导致页面被判定为重复。 本文从技术排查角度出发,整理6个最易被忽视但直接影响收录的实操问题。 页面加载速度拖慢爬虫抓取 例如&#xff0…