网络模型—BIO、NIO、IO多路复用、信号驱动IO、异步IO

一、用户空间和内核空间

  以Linux系统为例,ubuntu和CentOS是Linux的两种比较常见的发行版,任何Linux发行版,其系统内核都是Linux。我们在发行版上操作应用,如Redis、Mysql等其实是无法直接执行访问计算机硬件(如cpu,内存,网卡等)的操作的,所以需要借助发行版去访问内核,再通过内核去访问计算机硬件。
在这里插入图片描述

  那么问题来了,我们想要用户的应用来访问,计算机就必须要对外暴露一些接口,从而实现对内核的操控,但是内核本身上来说也是一个应用,所以他本身也需要一些内存,cpu等设备资源,用户应用本身也在消耗这些资源,如果不加任何限制,用户随意地去操作系统资源,就有可能导致一些冲突,甚至有可能导致系统出现无法运行的问题,所以把用户和内核隔离开是十分有必要的。因此,用户空间和内核空间应运而生。
  在Linux系统中,权限分成两个等级,0和3,用户空间只能执行受限的命令(Ring3),而且不能直接调用系统资源,而内核可以执行特权命令(Ring0),调用一切系统资源。所以一般情况下,用户的操作是运行在用户空间,而内核运行的数据是在内核空间的,而某些情况下,一个应用程序需要去调用一些特权资源,其就要去调用一些内核空间的操作,所以此时他需要在用户态和内核态之间进行切换。

注:
Linux系统为了提高IO效率,在用户空间和内核空间都加入缓冲区。
写数据时,要把用户缓冲区的数据拷贝到内核缓冲区,然后写入设备;
读数据时,要从设备读取数据到内核缓冲区,然后拷贝到用户缓冲区。
在这里插入图片描述
上图是用户应用读取数据时的流程图,其中用户在两个阶段需要等待:

  • 驱动程序从硬件上读取数据,内核会将读取到的数据写入到内核缓冲区
  • 将内核缓冲区的数据拷贝到用户缓冲区中

这也是不同网络模型主要优化的两个方面,在理解了上述流程后,我们正式进入到网络模型的介绍中!

二、网络模型

1. 阻塞IO(Blocking IO)

  用户读取数据时,会先发起一个recvform命令,尝试从内核上加载数据,如果内核没有数据,那么用户就会阻塞等待,此时内核会去从硬件上读取数据,内核读取数据之后,再把数据拷贝到用户空间,并且返回OK,整个过程,都是阻塞等待的,这就是阻塞IO。
在这里插入图片描述
总结:
顾名思义,阻塞IO就是两个阶段都必须阻塞等待。

阶段一:

  • 用户进程尝试读取数据(比如网卡数据)
  • 此时数据尚未到达,内核需要等待数据
  • 此时用户进程也处于阻塞状态

阶段二:

  • 数据到达并拷贝到内核缓冲区,代表已就绪
  • 将内核数据拷贝到用户缓冲区
  • 拷贝过程中,用户进程依然阻塞等待
  • 拷贝完成,用户进程解除阻塞,处理数据

2. 非阻塞IO(Nonblocking IO)

  用户读取数据时,会先发起一个recvform命令,尝试从内核上加载数据,如果内核没有数据,会返回给用户一个异常,之后用户会再次发起请求,直至数据就绪,之后把数据拷贝到用户空间,并且返回OK,在拷贝数据到用户空间时,是阻塞等待的,这就是非阻塞IO。
在这里插入图片描述
总结:
非阻塞IO的recvfrom操作会立即返回结果而不是阻塞用户进程。

阶段一:

  • 用户进程尝试读取数据(比如网卡数据)
  • 此时数据尚未到达,内核需要等待数据
  • 返回异常给用户进程
  • 用户进程拿到error后,再次尝试读取
  • 循环往复,直到数据就绪

阶段二:

  • 将内核数据拷贝到用户缓冲区
  • 拷贝过程中,用户进程依然阻塞等待
  • 拷贝完成,用户进程解除阻塞,处理数据

  可以看到,在非阻塞IO模型中,用户进程在第一个阶段是非阻塞,只有第二个阶段是阻塞状态。不过虽然是非阻塞,但其采用的是再次请求,因此性能并没有得到提高。而且忙等机制会导致CPU空转,CPU使用率暴增。

3. IO多路复用(IO Multiplexing)

  无论是阻塞IO还是非阻塞IO,用户应用在一阶段都需要调用recvfrom来获取数据,差别在于无数据时的处理方案,我们前面已经分析过,这两种方案性能都不好。
  而在单线程情况下,只能依次处理IO事件,如果正在处理的IO事件恰好未就绪(数据不可读或不可写),线程就会被阻塞,这会导致所有IO事件都必须等待(即使已经有就绪的事件),性能自然会很差。我们知道,Redis的网络模型就是IO多路复用,那么IO多路复用有何优化呢?
  在IO多路复用网络模型中,用户去读取数据时,不再去直接调用recvfrom了,而是调用select函数,select函数会将需要监听的数据交给内核,由内核去检查这些数据是否就绪了,如果说这个数据就绪了,就会通知应用程序数据就绪,然后来读取数据,再从内核空间把数据拷贝给用户空间,完成数据处理,如果所有的数据都没就绪,此时再进行等待。

在这里插入图片描述

总结:
  文件描述符(File Descriptor):简称FD,是一个从0开始的无符号整数,用来关联Linux中的一个文件。在Linux中一切皆文件,例如常规文件、视频、硬件设备等,当然也包括网络套接字(Socket)。
  IO多路复用利用单个线程来同时监听多个FD,并在某个FD可读、可写时得到通知,从而避免无效的等待,充分利用CPU资源。

阶段一:

  • 用户进程调用select,指定要监听的FD集合
  • 核监听FD对应的多个Socket
  • 任意一个或多个Socket数据就绪则返回readable
  • 此过程中用户进程阻塞

阶段二:

  • 用户进程找到就绪的Socket
  • 依次调用recvfrom读取数据
  • 内核将数据拷贝到用户空间
  • 用户进程处理数据

此外,在监听FD的方式、通知的方式有多种实现,常见的有:

  • select
  • poll
  • epoll

  其中select和poll相当于是当被监听的数据准备好之后,他会把你监听的FD整个数据都发给你,你需要到整个FD中去找哪些是就绪的,需要通过遍历的方式,所以性能也并不是那么好。而epoll,相当于数据准备好了之后,会把准备好的数据直接发给你,省去了遍历的动作,因此性能最好。

4. 信号驱动IO(Signal Driven IO)

  信号驱动IO是与内核建立SIGIO的信号关联并设置回调,当内核有FD就绪时,会发出SIGIO信号通知用户,期间用户应用可以执行其它业务,无需阻塞等待。
在这在这里插入图片描述
里插入图片描述

总结:
  当有大量IO操作时,信号较多,SIGIO处理函数不能及时处理可能导致信号队列溢出,而且内核空间与用户空间的频繁信号交互性能也较低。

阶段一:

  • 用户进程调用sigaction,注册信号处理函数
  • 内核返回成功,开始监听FD
  • 用户进程不阻塞等待,可以执行其它业务
  • 当内核数据就绪后,回调用户进程的SIGIO处理函数

阶段二:

  • 收到SIGIO回调信号
  • 调用recvfrom读取数据
  • 内核将数据拷贝到用户空间
  • 用户进程处理数据

5. 异步IO(Asynchronous IO)

  异步IO,不仅仅是用户态在试图读取数据后不阻塞,而且当内核的数据准备完成后,也不会阻塞。
在这里插入图片描述
总结:
  异步IO会由内核将所有数据处理完成后,包含将数据写入到用户空间中,才算完成,所以性能极高,不会有任何阻塞,全部都由内核完成。可以看到,异步IO模型中,用户进程在两个阶段都是非阻塞状态。不过其在高并发的情况下也存在一些问题,比如,用户应用发送了过多的IO请求,因为IO操作比较费时,那么在内核空间可能会积累很多IO任务,从而导致系统因为内存占用过多而崩溃。所以,异步IO需要采用合适的限流措施。

三、对比

在这里插入图片描述

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

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

相关文章

勒索软件分析_Conti

0. Conti介绍 勒索软件即服务(Ransomware as a Service,RaaS)变体 Conti 推出还不到两年,已经进行了第七次迭代。Conti被证明是一种敏捷而熟练的恶意软件威胁,能够自主和引导操作,并具有无与伦比的加密速度…

详细分析Element中的Drawer(附Demo)

目录 前言1. 基本知识2. Demo2.1 基本用法2.2 不同方向2.3 自定义大小2.4 嵌入表单2.5 嵌套抽屉 3. 实战4. Element Plus(Drawer) 前言 对于该组件针对Vue2比较多,而Element Plus中的Drawer针对Vue3比较多 此处的Demo主要偏向Vue2 后续的El…

探索 Mistral 新发布的具有原生函数调用功能的 7B 模型【附notebook文件】

引言 Mistral 发布了新版的 7B 模型,这次更新引入了原生函数调用功能。对于开发者和 AI 爱好者来说,这一更新极具吸引力,因为它增强了模型的功能和实用性。在这篇博客中,我们将深入探讨这些新功能,展示如何使用该模型…

小程序-修改用户头像

1、调用拍照 / 选择图片 // 修改头像 const onAvatarChange () > { // 调用拍照 / 选择图片 uni.chooseMedia({ // 文件个数 count: 1, // 文件类型 mediaType: [image], success: (res) > { console.log(res) // 本地临时文件路径 (本地路径) const { tempFilePath } …

wordpress主题模板兔Modown 9.1开心版附送erphpdown v17.1插件

Modown 9.1开心版是一款模板兔开发的wordpress主题可,持续更新多年,优秀的资源下载类主题该模板基于Erphpdown,可以销售软件、视频教程、文章等等,通过主题和插件结合可以实现付费下载、付费阅读等功能,配合模板兔的一…

数组-下一个排列

一、题目描述 二、解题思路 1.反向遍历当前排列,比如 排列A[a,b,c,d,e,f...] ,当遍历到e时,说明以 a,b,c,d,e为前缀的排列中不存在A排列的下一个排列。 2.把e(位置设为idx)和后面的元素作比较: 2.1 如果有…

【数据结构(邓俊辉)学习笔记】二叉树02——遍历

文章目录 0.概述1. 先序遍历1.1 递归版1.1.1 实现1.1.2 时间复杂度1.1.3 问题 1.2 迭代版11.3 迭代版21.3.1 思路1.3.2 实现1.3.3 实例 2. 中序遍历2.1 递归形式2.2 迭代形式2.2.1 观察2.2.2 思路(抽象总结)2.2.3 构思 实现2.2.4 分摊分析 3. 后序遍历3…

网络原理 一

一、协议 网络通信中,协议是非常重要的概念. 协议进行了分层,此处就是按照这几层顺序来介绍每一层中的核心协议. 应用层,就对应着应用程序,是程序员打交道最多的一层,调用系统提供的 网络api 写出的代码都是基于应用层的. 应用层这里当然也有很多现成的协议,但更多的还是,程…

JVM(三)

在上一篇中,介绍了JVM组件中的类加载器,以及相关的双亲委派机制。这一篇主要介绍运行时的数据区域 JVM架构图: JDK1.8后的内存结构: (图片来源:https://github.com/Seazean/JavaNote) 而在运行时数据区域中&#…

Vivado报错集合

Synth 8-5535 报错代码 [Synth 8-5535] port <clk_0> has illegal connections. It is illegal to have a port connected to an input buffer and other components. The following are the port connections : Input Buffer:Port I of instance clkin1_ibufg(IBUF) i…

SwiftUI中List的样式及使用详解(添加、移动、删除、自定义滑动)

SwiftUI中的List可是个好东西&#xff0c;它用于显示可滚动列表的视图容器&#xff0c;类似于UITableView。在List中可以显示静态或动态的数据&#xff0c;并支持垂直滚动。List是一个数据驱动的视图&#xff0c;当数据发生变化时&#xff0c;列表会自动更新。 针对List&#x…

树莓派4B 有电但无法启动

试过多个SD卡&#xff0c;反复烧系统镜像都无法启动。接HDMI显示器没有信号输出&#xff0c;上电后PWR红灯长亮&#xff0c;ACT绿灯闪一下就不亮了&#xff0c;GPIO几个电源脚有电&#xff0c;芯片会发热&#xff0c;测量多个TP点电压好像都正常。 ……

华为造车布局全曝光,对标奔驰、迈巴赫等

文 | Auto芯球 作者 | 雷慢 这一刻&#xff0c;我承认我格局小了&#xff0c; 就在刚刚&#xff0c;余承东曝光了华为智选车的布局计划&#xff0c; 华为问界、智界、享界等&#xff0c;将全面对标奔驰、迈巴赫、劳斯莱斯等车系&#xff0c; 这布局&#xff0c;确实是世界…

揭秘《庆余年算法番外篇》:范闲如何使用维吉尼亚密码解密二皇子密信

❤️❤️❤️ 欢迎来到我的博客。希望您能在这里找到既有价值又有趣的内容&#xff0c;和我一起探索、学习和成长。欢迎评论区畅所欲言、享受知识的乐趣&#xff01; 推荐&#xff1a;数据分析螺丝钉的首页 格物致知 终身学习 期待您的关注 导航&#xff1a; LeetCode解锁100…

【yolov10】使用自己的数据集训练目标检测模型

【yolov10】使用自己的数据集训练目标检测模型 一、anaconda安装二、环境配置三、数据集制作1、labelimg的安装2、使用labelimg 四、正片1、下载yolov10源码2、数据集目录3、训练4、推理 一、anaconda安装 直接参考前一篇博客&#xff1a; https://blog.csdn.net/m0_71523511/…

击穿盲点——【网络安全】社会工程学中的网络欺骗

社会工程学起源于上世纪60年代左右&#xff0c;是一种通过人际交流的方式来获得情报的非技术渗透手段。这种手段无需过多技术要求&#xff0c;却非常有效&#xff0c;目前已成为危害企业网络安全的重大威胁之一。著名黑客凯文米特尼克在《反欺骗的艺术》中曾提到&#xff0c;人…

SpringBoot+Vue开发记录(七)-- 跨域文件与Restful风格

本篇文章的主要内容是关于项目的跨域配置和给项目添加restful风格接口。 重点是文件粘贴 文章目录 一、 跨域二、Restful风格1. 什么是restful风格&#xff1f;2. 项目文件结构3. 新建文件4. 在Controller中进行修改 一、 跨域 跨域问题暂时也就那样&#xff0c;解决方法就是…

云计算-No-SQL 数据库 (No-SQL Database)

DynamoDB简介 (Introduction to DynamoDB) AWS DynamoDB 是亚马逊提供的一种 NoSQL 数据库&#xff0c;适用于需要快速访问的大规模应用程序。NoSQL 数据库指的是非关系型数据库&#xff08;或许应该称为“非关系数据库”&#xff09;。关系型数据库是你之前可能使用过的熟悉的…

深入Django项目实战与最佳实践

title: 深入Django项目实战与最佳实践 date: 2024/5/19 21:41:38 updated: 2024/5/19 21:41:38 categories: 后端开发 tags: Django 基础项目实战最佳实践数据库配置静态文件部署高级特性 第一章&#xff1a;Django项目架构与设计原则 Django框架概述 Django是一个高级的P…