day36-多路IO复用

news2025/6/13 7:36:17

一、基本概念

(服务器多客户端模型)


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


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


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

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


使用并发处理的成本:
    线程/进程创建成本
    CPU切换不同线程/进程成本 Context Switch        (上下文切换:页表、寄存器、缓存)
    多线程的资源竞争


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

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

    

二、IO模型

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

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:

  1. 创建fd集合(二叉树)
  2. 加入关心的文件描述符
  3. epoll_wait                 当 epoll_wait 成功时,它返回准备就绪的文件描述符的数量,如果超时则返回 0。如果发生错误,则返回 -1 并设置相应的 errno
  4. 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.coloradmin.cn/o/2407127.html

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

相关文章

群晖NAS如何在虚拟机创建飞牛NAS

套件中心下载安装Virtual Machine Manager 创建虚拟机 配置虚拟机 飞牛官网下载 https://iso.liveupdate.fnnas.com/x86_64/trim/fnos-0.9.2-863.iso 群晖NAS如何在虚拟机创建飞牛NAS - 个人信息分享

android13 app的触摸问题定位分析流程

一、知识点 一般来说,触摸问题都是app层面出问题,我们可以在ViewRootImpl.java添加log的方式定位;如果是touchableRegion的计算问题,就会相对比较麻烦了,需要通过adb shell dumpsys input > input.log指令,且通过打印堆栈的方式,逐步定位问题,并找到修改方案。 问题…

基于PHP的连锁酒店管理系统

有需要请加文章底部Q哦 可远程调试 基于PHP的连锁酒店管理系统 一 介绍 连锁酒店管理系统基于原生PHP开发,数据库mysql,前端bootstrap。系统角色分为用户和管理员。 技术栈 phpmysqlbootstrapphpstudyvscode 二 功能 用户 1 注册/登录/注销 2 个人中…

基于Java+VUE+MariaDB实现(Web)仿小米商城

仿小米商城 环境安装 nodejs maven JDK11 运行 mvn clean install -DskipTestscd adminmvn spring-boot:runcd ../webmvn spring-boot:runcd ../xiaomi-store-admin-vuenpm installnpm run servecd ../xiaomi-store-vuenpm installnpm run serve 注意:运行前…

MacOS下Homebrew国内镜像加速指南(2025最新国内镜像加速)

macos brew国内镜像加速方法 brew install 加速formula.jws.json下载慢加速 🍺 最新版brew安装慢到怀疑人生?别怕,教你轻松起飞! 最近Homebrew更新至最新版,每次执行 brew 命令时都会自动从官方地址 https://formulae.…

Qemu arm操作系统开发环境

使用qemu虚拟arm硬件比较合适。 步骤如下: 安装qemu apt install qemu-system安装aarch64-none-elf-gcc 需要手动下载,下载地址:https://developer.arm.com/-/media/Files/downloads/gnu/13.2.rel1/binrel/arm-gnu-toolchain-13.2.rel1-x…

STM32---外部32.768K晶振(LSE)无法起振问题

晶振是否起振主要就检查两个1、晶振与MCU是否兼容;2、晶振的负载电容是否匹配 目录 一、判断晶振与MCU是否兼容 二、判断负载电容是否匹配 1. 晶振负载电容(CL)与匹配电容(CL1、CL2)的关系 2. 如何选择 CL1 和 CL…

Python 实现 Web 静态服务器(HTTP 协议)

目录 一、在本地启动 HTTP 服务器1. Windows 下安装 node.js1)下载安装包2)配置环境变量3)安装镜像4)node.js 的常用命令 2. 安装 http-server 服务3. 使用 http-server 开启服务1)使用 http-server2)详解 …

PHP 8.5 即将发布:管道操作符、强力调试

前不久,PHP宣布了即将在 2025 年 11 月 20 日 正式发布的 PHP 8.5!作为 PHP 语言的又一次重要迭代,PHP 8.5 承诺带来一系列旨在提升代码可读性、健壮性以及开发者效率的改进。而更令人兴奋的是,借助强大的本地开发环境 ServBay&am…

【Linux系统】Linux环境变量:系统配置的隐形指挥官

。# Linux系列 文章目录 前言一、环境变量的概念二、常见的环境变量三、环境变量特点及其相关指令3.1 环境变量的全局性3.2、环境变量的生命周期 四、环境变量的组织方式五、C语言对环境变量的操作5.1 设置环境变量:setenv5.2 删除环境变量:unsetenv5.3 遍历所有环境…

Chromium 136 编译指南 Windows篇:depot_tools 配置与源码获取(二)

引言 工欲善其事,必先利其器。在完成了 Visual Studio 2022 和 Windows SDK 的安装后,我们即将接触到 Chromium 开发生态中最核心的工具——depot_tools。这个由 Google 精心打造的工具集,就像是连接开发者与 Chromium 庞大代码库的智能桥梁…

脑机新手指南(七):OpenBCI_GUI:从环境搭建到数据可视化(上)

一、OpenBCI_GUI 项目概述 (一)项目背景与目标 OpenBCI 是一个开源的脑电信号采集硬件平台,其配套的 OpenBCI_GUI 则是专为该硬件设计的图形化界面工具。对于研究人员、开发者和学生而言,首次接触 OpenBCI 设备时,往…

Unity UGUI Button事件流程

场景结构 测试代码 public class TestBtn : MonoBehaviour {void Start(){var btn GetComponent<Button>();btn.onClick.AddListener(OnClick);}private void OnClick(){Debug.Log("666");}}当添加事件时 // 实例化一个ButtonClickedEvent的事件 [Formerl…

Web后端基础(基础知识)

BS架构&#xff1a;Browser/Server&#xff0c;浏览器/服务器架构模式。客户端只需要浏览器&#xff0c;应用程序的逻辑和数据都存储在服务端。 优点&#xff1a;维护方便缺点&#xff1a;体验一般 CS架构&#xff1a;Client/Server&#xff0c;客户端/服务器架构模式。需要单独…

【从零开始学习JVM | 第四篇】类加载器和双亲委派机制(高频面试题)

前言&#xff1a; 双亲委派机制对于面试这块来说非常重要&#xff0c;在实际开发中也是经常遇见需要打破双亲委派的需求&#xff0c;今天我们一起来探索一下什么是双亲委派机制&#xff0c;在此之前我们先介绍一下类的加载器。 目录 ​编辑 前言&#xff1a; 类加载器 1. …

c++第七天 继承与派生2

这一篇文章主要内容是 派生类构造函数与析构函数 在派生类中重写基类成员 以及多继承 第一部分&#xff1a;派生类构造函数与析构函数 当创建一个派生类对象时&#xff0c;基类成员是如何初始化的&#xff1f; 1.当派生类对象创建的时候&#xff0c;基类成员的初始化顺序 …

淘宝扭蛋机小程序系统开发:打造互动性强的购物平台

淘宝扭蛋机小程序系统的开发&#xff0c;旨在打造一个互动性强的购物平台&#xff0c;让用户在购物的同时&#xff0c;能够享受到更多的乐趣和惊喜。 淘宝扭蛋机小程序系统拥有丰富的互动功能。用户可以通过虚拟摇杆操作扭蛋机&#xff0c;实现旋转、抽拉等动作&#xff0c;增…

Proxmox Mail Gateway安装指南:从零开始配置高效邮件过滤系统

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐&#xff1a;「storms…

毫米波雷达基础理论(3D+4D)

3D、4D毫米波雷达基础知识及厂商选型 PreView : https://mp.weixin.qq.com/s/bQkju4r6med7I3TBGJI_bQ 1. FMCW毫米波雷达基础知识 主要参考博文&#xff1a; 一文入门汽车毫米波雷达基本原理 &#xff1a;https://mp.weixin.qq.com/s/_EN7A5lKcz2Eh8dLnjE19w 毫米波雷达基础…

TSN交换机正在重构工业网络,PROFINET和EtherCAT会被取代吗?

在工业自动化持续演进的今天&#xff0c;通信网络的角色正变得愈发关键。 2025年6月6日&#xff0c;为期三天的华南国际工业博览会在深圳国际会展中心&#xff08;宝安&#xff09;圆满落幕。作为国内工业通信领域的技术型企业&#xff0c;光路科技&#xff08;Fiberroad&…