当前位置: 首页 > news >正文

sheng的学习笔记-IO多路复用,NIO,BIO,AIO

基础概念

IO分为几种:同步阻塞的BIO,同步非阻塞的NIO,异步非阻塞AIO,IO多路复用,信号驱动IO(不常用)

对于一个network IO,它会涉及到两个系统对象,一个是调用这个IO的process(Thread),另一个是系统内核。当一个read/recv读数据的操作发生时,该操作会经历两个阶段:

  (1)等待数据准备

  (2)将数据从内核拷贝到进程中

BIO:同步并阻塞

服务端处理请求是串联的。也就是说如果这个请求被阻塞了,那么剩下的请求都要被阻塞``等待``上一个请求处理完成才行。所以,我们上面说,在 服务器读数据的时候,数据还没到(数据还没读到用户态),那么服务器被阻塞,然后其他客户端的请求也不能被处理。

比如:
小明和小红两个人访问同一个服务,然后小明先点,但是数据没被处理完成,然后小红在进行发送请求,此时服务器就将小红的请求挂起,等待小明的处理完成在进行处理。

而且小明发了申请,服务器没有返回响应之前,小明也不能动,阻塞在那里等待到应答,才能继续做别的事情

.

NIO:同步非阻塞

用户线程发起IO请求后,立即返回;这时候可以干点别的,过一会再查,但需要不断地调用read,尝试读取socket中的数据,直到读取成功后,才继续处理接收的数据。

虽然用户线程每次发起IO请求后可以立即返回,但是为了等到数据,仍需要不断地轮询、重复请求,消耗了大量的CPU的资源。一般很少直接使用这种模型,而是在其他IO模型中使用非阻塞IO这一特性。

当用户进程发出read操作时,如果kernel中的数据还没准备好,那么它并不会block用户进程,而是立刻返回一个error。当用户进程接收到一个error,就会知道数据还没准备,于是用户就可以做点其他的,过一段时间,再次发送read操作,一旦kernel的数据准备好了,他就会立马把数据拷贝到了用户内存,然后返回。

  在这种非阻塞IO模式下,用户进程就不断的询问kernel的数据准备好了没,若没有,返回给 用户一个error,在两次询问期间,用户进程可以干点其他的,若数据准备好了,就直接拷贝,这个询问过程叫轮询。在拷贝数据整个过程,进程任仍然处于阻塞状态

IO多路复用

一个线程内同时处理多个IO请求,这就是IO多路复用

相当于select\epoll,这种IO方式也称为事件驱动IO,select\epoll的好处在于单个process就可以同时处理多个网络连接的IO。它的基本原理就是select\epoll这个function会不断的轮询所负责的所有socket,当某个socket有数据响应了,就通知用户进程。

当用户进程调用了select,那么整个进程会被block,而同时,kernel会“监视”所有select负责的socket,当任何一个socket中的数据准备好了,select就会返回。这个时候用户进程再调用read操作,将数据从kernel拷贝到用户进程。

  这个图和blocking IO的图其实并没有太大的不同,事实上还更差一些。因为它不仅阻塞了还多需要使用两个系统调用(select和recvfrom),而blocking IO只调用了一个系统调用(recvfrom),当只有一个连接请求的时候,这个模型还不如阻塞IO效率高。但是,用select的优势在于它可以同时处理多个connection,而阻塞IO那里不能,我不管阻塞不阻塞,你所有的连接包括recv等操作,我都帮你监听着(以什么形式监听的呢?先不要考虑,下面会讲的~~),其中任何一个有变动(有链接,有数据),我就告诉你用户,那么你就可以去调用这个数据了,这就是他的NB之处。

  select模块及使用方法:select的优势在于处理多个连接,不适用于单个连接

虽然上述方式允许单线程内处理多个IO请求,但是每个IO请求的过程还是阻塞的(在select函数上阻塞),平均时间甚至比同步阻塞IO模型还要长。如果用户线程只注册自己感兴趣的socket或者IO请求,然后去做自己的事情,等到数据到来时再进行处理,则可以提高CPU的利用率。以下是改良版:

reactor设计模式,就是基于IO多路复用,可以参考

https://blog.csdn.net/coldstarry/article/details/129433822

AIO:异步IO

   用户进程发起read操作之后,立刻就可以开始去做其它的事。而另一方面,从kernel的角度,当它受到一个asynchronous read之后,首先它会立刻返回,所以不会对用户进程产生任何block。然后,kernel操作系统会等待数据(阻塞)准备完成,然后将数据拷贝到用户内存,当这一切都完成之后,kernel会给用户进程发送一个signal,告诉它read操作完成了。

  貌似异步IO这个模型很牛~~但是你发现没有,这不是我们自己代码控制的,都是操作系统完成的,而python在copy数据这个阶段没有提供操纵操作系统的接口,所以用python没法实现这套异步IO机制,其他几个IO模型都没有解决第二阶段的阻塞(用户态和内核态之间copy数据),但是C语言是可以实现的,因为大家都知道C语言是最接近底层的,虽然我们用python实现不了,但是python仍然有异步的模块和框架(tornado、twstied,高并发需求的时候用),这些模块和框架很多都是用底层的C语言实现的,它帮我们实现了异步,你只要使用就可以了,但是你要知道这个异步是不是很好呀,不需要你自己等待了,操作系统帮你做了所有的事情,你就直接收数据就行了,就像你有一张银行卡,银行定期给你打钱一样。

信号驱动IO

信号驱动IO: 内核将数据准备好的时候, 使用SIGIO信号通知应用程序进行IO操作

通知应用程序处理IO, 是开始处理IO, 这个时候还是存在阻塞的,将数据从内核态拷贝进入到用户态的过程至少是阻塞住的 (应用程序将数据从内核态拷贝到用户态的过程是阻塞等待的, 和异步IO的区别) (此处是区分信号驱动IO和异步IO的关键所在)

信号驱动IO, 我们提前在信号集合中设置好IO信号等待, 注册好对应的IO处理函数 handler,IO数据准备就绪后,会递交SIGIO信号,通知应用程序中断然后开始进行对应的IO处理逻辑. 但是通知处理IO的时候存在将数据从 内核空间拷贝到用户空间的过程,(而异步IO是数据拷贝完成之后内核再通知应用程序直接开始处理, 应用程序直接处理,不需要拷贝数据阻塞等待)

各IO对比

参考文章

https://blog.csdn.net/guorui_java/article/details/107081776

https://www.cnblogs.com/zhangxiaoji/p/16152141.html

https://zhuanlan.zhihu.com/p/555459665

https://www.cnblogs.com/12345huangchun/p/10066840.html

https://blog.csdn.net/leftfist/article/details/105020228

相关文章:

sheng的学习笔记-IO多路复用,NIO,BIO,AIO

基础概念IO分为几种:同步阻塞的BIO,同步非阻塞的NIO,异步非阻塞AIO,IO多路复用,信号驱动IO(不常用)对于一个network IO,它会涉及到两个系统对象,一个是调用这个IO的proce…...

【Python入门第三十五天】Python丨文件打开

在服务器上打开文件 假设我们有以下文件,位于与 Python 相同的文件夹中。 demofile.txt Hello! Welcome to demofile.txt This file is for testing purposes. Good Luck!如需打开文件,请使用内建的 open() 函数。 open() 函数返回文件对象&#xff…...

jsoup 框架的使用指南

概述 参考: 官方文档jsoup的使用JSoup教程jsoup 在 GitHub 的开源代码 概念简介 jsoup 是一款基于 Java 的 HTML 解析器,它提供了一套非常省力的 API,不但能直接解析某个 URL 地址、HTML 文本内容,而且还能通过类似于 DOM、CS…...

web前端开发和后端开发哪个难度大?

前言 因为涉及到的具体的应用的领域不同,所以说不能简单地说哪一个难,对于前端而言你会感觉到入门会非常的简单,这也是会给许多人一种错觉,前端很简单,但是只能说是在入门理解上是有利于新手的,前端在主要…...

认证与认可之间有什么区别和联系?

认证与认可之间有什么区别和联系? 当今社会,认证与认可已经深入企业的生活,那么认证与认可之间到底有什么区别和联系呢? 认证,是指由认证机构证明产品、服务、管理体系符合相关技术规范、相关技术规范的强制性要求或者…...

【Java|golang】1626. 无矛盾的最佳球队---最长子序列,不连续,二维数组排序

假设你是球队的经理。对于即将到来的锦标赛,你想组合一支总体得分最高的球队。球队的得分是球队中所有球员的分数 总和 。 然而,球队中的矛盾会限制球员的发挥,所以必须选出一支 没有矛盾 的球队。如果一名年龄较小球员的分数 严格大于 一名…...

C++ 八股文(简单面试题)

1.左值 可寻址变量,持久性; 2.右值 没有变量名,不可寻址,短暂性; 3.指针 指向的内存地址,指针变量存储的就是指向的对象的首地址 4.引用 为一个变量起别名,定义引用的时候一定要初始化&a…...

RK3588平台开发系列讲解(显示篇)DP显示调试方法

平台内核版本安卓版本RK3588Linux 5.10Android 12文章目录 一、查看 connector 状态二、强制使能/禁⽤ DP三、DPCP 读写四、Type-C 接口 Debug五、查看 DP 寄存器六、查看 VOP 状态七、查看当前显示时钟八、调整 DRM log 等级沉淀、分享、成长,让自己和他人都能有所收获!😄…...

模拟请求发生跨域问题

参考:传送门 问题产生: Access to XMLHttpRequest at ‘http://test-cms.jinhuahuolong.com/api/pages/list’ from origin ‘null’ has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resourc…...

Qt实践项目:仿Everything软件实现一个QtEverything

⭐️我叫忆_恒心,一名喜欢书写博客的在读研究生👨‍🎓。 如果觉得本文能帮到您,麻烦点个赞👍呗! 近期会不断在专栏里进行更新讲解博客~~~ 有什么问题的小伙伴 欢迎留言提问欧,喜欢的小伙伴给个三…...

WEB网站服务(一)

1.1 Apache网站服务基础1.1.1Apache简介Apache HTTP Server是开源软件项目的杰出代表,基于标准的HTTP网络协议提供网页浏览服务。Apache服务器可以运行在Linux,UNIX,windows等多种操作系统平台中。1.Apache的起源1995年,Apache服务程序的1.0版…...

Python数据分析script必备知识(一)

Python数据分析script必备知识(一) 1.重定向终端输出内容 使生成的结果移动到其他位置 # 重定向, 使生成的结果移动到其他位置 import syssys.stderr = sys.stdoutprint(dir(sys)) # ,,,,,__stderr__, __stdin__, __stdout__,,,,,,# 使用场景:脚本上线时,想要把输出结果…...

初识linux之管道

一、进程间通信的概念大家都知道,进程是具有独立性的,因为一个程序运行起来生成进程时,也会生成它的进程结构体,即PCB,然后然后通过进程结构体中的结构体指针找到它的虚拟地址空间,然后再通过它的页表映射到…...

C++成神之路 | 第一课【步入C++的世界】

目录 一、认识C++ 1.1、关于 C++ 1.2、C++的前世今生 1.2.1、C+...

【面试题】大厂面试官:你做过什么有亮点的项目吗?

大厂面试题分享 面试题库前后端面试题库 (面试必备) 推荐:★★★★★地址:前端面试题库前言大厂面试中除了问常见的算法网络基础,和一些八股文手写体之外,经常出现的一个问题就是,你做过什么项目…...

Springboot Long类型数据太长返回给前端,精度丢失问题 复现、解决

前言 惯例,收到兄弟求救,关于long类型丢失精度的问题: 存在一个初学者不会,就会有第二个初学者不会,所以我出手。 正文 不多说,开搞。 如题, 后端返回的数据 给到 前端, Long类型数…...

Anaconda虚拟环境的创建方法(命令创建)

虚拟环境介绍: 虚拟环境是一为某个项目创建的专属于它的python包,因此做python项目时,一般一个项目用一个虚拟环境。在实际开发中,如果项目A需要某个包的1.0版本,项目B需要此包的2.0版本。如果没有安装虚拟环境&#…...

数据结构——树与二叉树

作者:几冬雪来 时间:2023年3月22日 内容:数据结构树与二叉树的讲解(介绍) 目录 前言: 1.树的概念: 2.树与非树: 3.树的定义: 4.树的应用: 二叉树&…...

vue后台管理系统

后面可参考下:vue系列(三)——手把手教你搭建一个vue3管理后台基础模板 以下代码项目gitee地址 文章目录1. 初始化前端项目初始化项目添加加载效果配置 vite.config.js2. 使用路由安装路由配置路由配置别名和跳转安装pathvite.config.jsjsco…...

spring boot 集成 postgis jar

要将 PostGIS 集成到 Spring Boot 应用程序中,需要按照以下步骤进行操作:1. 将 PostGIS JDBC 驱动程序添加到项目依赖项中。可以在 Maven 或 Gradle 中添加以下依赖项:Maven:```xml <dependency><groupId>org.postgresql</groupId><artifactId>pos…...

2025年能源电力系统与流体力学国际会议 (EPSFD 2025)

2025年能源电力系统与流体力学国际会议&#xff08;EPSFD 2025&#xff09;将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会&#xff0c;EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...

什么是库存周转?如何用进销存系统提高库存周转率?

你可能听说过这样一句话&#xff1a; “利润不是赚出来的&#xff0c;是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业&#xff0c;很多企业看着销售不错&#xff0c;账上却没钱、利润也不见了&#xff0c;一翻库存才发现&#xff1a; 一堆卖不动的旧货…...

基于数字孪生的水厂可视化平台建设:架构与实践

分享大纲&#xff1a; 1、数字孪生水厂可视化平台建设背景 2、数字孪生水厂可视化平台建设架构 3、数字孪生水厂可视化平台建设成效 近几年&#xff0c;数字孪生水厂的建设开展的如火如荼。作为提升水厂管理效率、优化资源的调度手段&#xff0c;基于数字孪生的水厂可视化平台的…...

HBuilderX安装(uni-app和小程序开发)

下载HBuilderX 访问官方网站&#xff1a;https://www.dcloud.io/hbuilderx.html 根据您的操作系统选择合适版本&#xff1a; Windows版&#xff08;推荐下载标准版&#xff09; Windows系统安装步骤 运行安装程序&#xff1a; 双击下载的.exe安装文件 如果出现安全提示&…...

Rust 异步编程

Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...

NFT模式:数字资产确权与链游经济系统构建

NFT模式&#xff1a;数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新&#xff1a;构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议&#xff1a;基于LayerZero协议实现以太坊、Solana等公链资产互通&#xff0c;通过零知…...

用docker来安装部署freeswitch记录

今天刚才测试一个callcenter的项目&#xff0c;所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...

HashMap中的put方法执行流程(流程图)

1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中&#xff0c;其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下&#xff1a; 初始判断与哈希计算&#xff1a; 首先&#xff0c;putVal 方法会检查当前的 table&#xff08;也就…...

IP如何挑?2025年海外专线IP如何购买?

你花了时间和预算买了IP&#xff0c;结果IP质量不佳&#xff0c;项目效率低下不说&#xff0c;还可能带来莫名的网络问题&#xff0c;是不是太闹心了&#xff1f;尤其是在面对海外专线IP时&#xff0c;到底怎么才能买到适合自己的呢&#xff1f;所以&#xff0c;挑IP绝对是个技…...

算法:模拟

1.替换所有的问号 1576. 替换所有的问号 - 力扣&#xff08;LeetCode&#xff09; ​遍历字符串​&#xff1a;通过外层循环逐一检查每个字符。​遇到 ? 时处理​&#xff1a; 内层循环遍历小写字母&#xff08;a 到 z&#xff09;。对每个字母检查是否满足&#xff1a; ​与…...