IO技术详解
IO监控项在监控中一直是很重要的存在,服务有IO,磁盘有IO,操作系统也有IO,IO到底是什么呢
IO
IO,即“输入/输出”(Input/Output),是指计算机系统或设备之间交换数据的过程。这个概念在计算机科学、电子学和网络通信中应用广泛。IO 主要涉及两种操作: 输入 (Input):系统或设备接收的数据。例如,键盘输入的字符、网络接收的数据包,或磁盘读取的文件内容等。 输出 (Output):系统或设备输出的数据。例如,屏幕上显示的文本、网络发送的数据包,或写入磁盘的文件内容等。 IO 操作的目的通常是为了完成数据在不同组件或设备之间的传输和存储。它们通常有不同的表现形式,比如: 文件 IO:对文件的读写操作。 网络 IO:在网络连接中发送和接收数据。 设备 IO:对硬件设备(如硬盘、键盘、显示器等)进行的读写操作。 涉及计算机核心与其他设备间数据迁移的过程,就是IO。如磁盘IO,就是从磁盘读取数据到内存,这算一次输入,对应的,将内存中的数据写入磁盘,就算输出。 IO 操作可能受到硬件的物理限制,因而通常是系统性能的瓶颈之一 操作系统将内存空间分为用户空间和内核空间,用户空间是用户访问的内存区域,内核空间是操作系统访问的区域 我们的应用程序是跑在用户空间的,不存在实质的IO过程,真正的IO是在操作系统进行的 应用程序IO分为2部分,一是IO执行,操作系统执行,一是IO调用,应用调用操作系统的IO,
同步异步IO
同步 IO:在此下,程序会等待 IO 操作完成后再继续执行。这种方式比较简单,但可能导致程序因为等待 IO 而浪费大量时间。
异步 IO:程序在发起 IO 请求后无需等待 IO 完成,可以继续执行其他任务。IO 完成后,系统会通知程序,或让程序在空闲时自行检查 IO 状态。这种方式提高了系统资源利用率和并发性能。
在传统的同步IO模型中,程序会被某个IO操作阻塞,直到该操作完成后才会继续执行。而异步IO模型的核心思想是“不要等待”,即发起一个IO操作后,程序不会等待结果,而是通过事件通知或回调函数在IO操作完成后被告知结果。这样,程序在处理多个IO任务时就不会因为等待而卡住。
异步IO的实现方式
-
回调函数:在发起异步IO时,传入一个回调函数,在操作完成后执行该回调函数。这种方式在JavaScript中尤为常见,例如Node.js的事件驱动模型。
-
Future/Promise:Future和Promise是异步编程中的抽象,用于存储异步操作的结果。通过检查Promise的状态,可以判断异步操作是否完成并获取结果。这种模式在Python、Java等语言中也得到了广泛应用。
-
事件循环(Event Loop):事件循环是实现异步IO的常用机制,程序运行在一个单线程上,由事件循环负责监控事件队列中的任务,依次处理完成的任务。例如,Node.js通过事件循环处理异步操作。
异步IO的优缺点
优点
-
高效的资源利用:异步IO使程序不必等待IO操作的完成,从而充分利用CPU资源。
-
高并发支持:适合处理大量并发请求,尤其在网络服务器、数据库等I/O密集型应用中。
缺点
-
代码复杂度增加:引入了回调函数、事件循环等机制,程序逻辑会较同步模型复杂。
-
调试难度增加:错误追踪和调试相对困难,尤其是在多层嵌套回调的情况下。
异步IO的应用场景
-
Web服务器:如Node.js,专为高并发和网络请求设计,擅长处理大量并发连接。
-
数据库操作:异步IO可以减少数据库连接等待时间,提高查询性能。
-
文件读写:尤其在文件传输、大规模文件处理场景中,通过异步处理文件读写,提升整体效率。
在Python中,可以使用asyncio库实现异步IO
import asyncio
async def fetch_data():print("Start fetching")await asyncio.sleep(2) # 模拟IO操作print("Data fetched")return "data"
async def main():result = await fetch_data()print(result)
# 执行异步任务
asyncio.run(main())
fetch_data()是一个异步任务,通过await关键字实现非阻塞的IO操作
阻塞非阻塞IO
阻塞IO
在阻塞 IO 模式中,程序在发起 IO 操作后会被“阻塞”,即停止执行其他操作,直到 IO 操作完成。只有当数据完全读取或写入时,程序才会继续执行后续代码。内核数据没有准备好,用户进程则会一直等待,影响性能
特点
-
简单易实现,常用于同步编程。
-
程序会一直等待 IO 操作完成,导致 CPU 资源的利用率较低,可能造成性能瓶颈。
-
适合对延迟要求不高的应用程序,或 IO 操作时间较短的场景。
# 阻塞 IO 示例
import socket
sock = socket.socket()
sock.connect(('example.com', 80))
sock.send(b'GET / HTTP/1.1\r\nHost: example.com\r\n\r\n')
response = sock.recv(4096) # 阻塞,等待接收数据
print(response)
sock.close()
非阻塞IO
在非阻塞 IO 模式中,程序发起 IO 操作后,不会等待 IO 操作完成,而是立即返回。程序可以继续执行其他任务,随时检查 IO 状态或等待系统通知 IO 操作的完成。
特点
-
更高效,适合并发处理和多任务的场景。
-
常与轮询(不断检查 IO 状态)或事件通知机制结合使用,比如
select()、poll()、epoll()等。 -
实现稍复杂,但能有效避免因等待 IO 而浪费 CPU 资源。
# 非阻塞 IO 示例
import socket
sock = socket.socket()
sock.setblocking(False) # 设置为非阻塞模式
try:sock.connect(('example.com', 80)) # 发起连接
except BlockingIOError:# 非阻塞模式下立即返回,跳过阻塞状态pass
# 继续做其他事情
# 稍后再检查连接是否成功或有数据返回
IO多路复用
但是无效的轮询也会加大内存的开销
IO 多路复用是一种高效的 IO 模型,允许一个线程同时监视多个 IO 操作。它的核心思想是让操作系统帮助检测哪些 IO 资源已经准备好进行读写,而不是让每个 IO 操作都单独等待。这样可以有效地提高系统资源利用率,尤其适合处理大量并发连接的场景,如网络服务器。
在 IO 多路复用中,常用的系统调用包括 select、poll 和 epoll:
常用的 IO 多路复用方法
-
select
-
select是最早实现 IO 多路复用的系统调用,通过一个文件描述符集合来监控多个 IO 通道。 -
它的调用会阻塞进程,直到一个或多个文件描述符变为就绪(可读、可写或有异常发生),然后程序可以对就绪的文件描述符执行 IO 操作。
-
缺点在于文件描述符集合的大小有限,且需要遍历所有的文件描述符,性能较低。
-
-
poll
-
poll是select的改进版,没有文件描述符数量限制,解决了select的一些不足。 -
poll通过一个数组而非集合来管理文件描述符,但仍然需要轮询所有文件描述符,且每次调用都需要重新构建文件描述符数组。 -
随着文件描述符数量增加,
poll的性能会下降。
-
-
epoll
-
epoll是 Linux 下的高效 IO 多路复用方式,针对select和poll的性能问题进行了优化。 -
epoll的文件描述符不需要重复传递,且支持“边缘触发(edge-triggered)”和“水平触发(level-triggered)”两种模式,能够更高效地检测文件描述符的状态变化。 -
它适合处理大量并发连接,被广泛用于高并发服务器(如 Nginx、Redis)中。
-
IO 多路复用的工作流程
-
程序创建并注册多个 IO 事件(文件描述符),告诉操作系统哪些事件需要监控。
-
操作系统负责检测文件描述符的状态变化,直到某些 IO 事件就绪,然后通知程序。
-
程序收到通知后,仅对就绪的 IO 事件执行读写操作,避免了阻塞等待,从而实现高效处理。
IO 多路复用的优势
-
高效性:程序无需轮询所有 IO 操作,而是让操作系统通知哪些 IO 就绪,避免了不必要的 CPU 消耗。
-
支持并发:一个线程可监控多个 IO 操作,适合高并发应用场景,避免了线程或进程创建的资源开销。
-
提高资源利用率:通过集中管理 IO 操作,可以大幅减少阻塞时间,让程序高效利用 CPU。
import select
import socket
# 创建两个监听 socket
sock1 = socket.socket()
sock1.bind(('0.0.0.0', 8000))
sock1.listen()
sock2 = socket.socket()
sock2.bind(('0.0.0.0', 8001))
sock2.listen()
# 把 socket 放入 select 监控列表
inputs = [sock1, sock2]
outputs = []
while True:# 调用 select,监控 inputs 列表中的 socket 是否有数据就绪readable, writable, exceptional = select.select(inputs, outputs, inputs)
for s in readable:if s is sock1 or s is sock2:# 有新的连接请求conn, addr = s.accept()print(f"Connection from {addr}")inputs.append(conn)else:# 处理现有连接的数据data = s.recv(1024)if data:print("Received:", data.decode())s.send(b"Echo: " + data)else:# 连接关闭print("Closing connection")inputs.remove(s)s.close()
在这个例子中,select.select() 会阻塞进程,直到有 IO 事件发生。通过这种方式,可以用一个线程或进程处理多个客户端连接,从而有效利用资源。
IO模型
| 阻塞IO | 同步阻塞 |
|---|---|
| 非阻塞IO | 同步非阻塞 |
| IO多路复用 | 同步阻塞 |
| 异步IO | 异步非阻塞 |
相关文章:
IO技术详解
IO监控项在监控中一直是很重要的存在,服务有IO,磁盘有IO,操作系统也有IO,IO到底是什么呢 IO IO,即“输入/输出”(Input/Output),是指计算机系统或设备之间交换数据的过程。这个概念…...
pySpark乱码
1.现象 python的变量包含中文,用format放入SQL中时,出现乱码 2.原因 python2默认编码是ascii 3.解决办法 使用python3,并且把所有print,改成带括号的 4.在pyspark中加入参数 spark.pyspark.driver.python/usr/bin/python3 …...
【MySQL 保姆级教学】事务的隔离级别(详细)--下(13)
事务的隔离级别 1. 如何理解事务的隔离性2. 事务隔离级别的分类3. 查看和设置事务隔离级别3.1 全局和会话隔离级别3.2 查看和设置隔离级别 4. 事务隔离级别的演示4.1 读未提交(Read Uncommitted)4.2 读已提交(Read Committed)4.3 …...
SpringBoot(十三)SpringBoot配置webSocket
在PHP版本的博客中,我使用PHPswoole实现了webscoket即时聊天的功能。 在java版本的博客中,我也想使用webscoket来实现即时聊天的功能,下边是我实现过程的一个记录。 一:在pom.xml中添加记录 <!-- spring-websocket start --&…...
OA系统都有哪些功能?OA办公系统功能大测评
随着现代企业对效率和协作的需求不断增加,OA办公系统已成为许多企业日常运营的重要工具。 一个功能完备的OA系统不仅能帮助企业提高办公效率,还能优化各类工作流程,从文档管理到审批流程、任务管理等,它为企业提供了全方位的支持…...
优化布线拥塞
Note:文章内容以 Xilinx 系列 FPGA 进行讲解 随着设计规模的增大和复杂度的提升,布线拥塞成为常见的问题,尤其是在用UltraScale FPGA或UltraScale FPGA时,布线拥塞往往成为时序收敛的瓶颈,也成为编译时间过长的“罪魁…...
盲盒APP开发,电商模式下盲盒的未知乐趣
在互联网电商模式逐渐成熟的当下,盲盒电商为消费者提供了一个全新的娱乐购物体验,让众多粉丝和消费者通过手机系统就可以体验拆盲盒的惊喜感和刺激性。在消费者享受线上拆盲盒的乐趣时,企业也能够获得新的发展机遇,扩大发展空间。…...
RocketMQ-02 集群架构部署
根据上一章《RocketMQ消费模型和部署模型》得知,启动rocketmq非常简单,只需要分别执行mqnamesrv启动NameServer,执行mqbroker启动Broker即可。但生产环境不可能仅使用单节点MQ,为提高可用性和吞吐量,生产常使用集群模式…...
处理报文后 展示在qtdesigner界面 ,有大量数据存储 怎样创建临时文件减少内存占用
处理大量数据并将其展示在 Qt Designer 创建的界面中时,确实可能会遇到内存占用过高的问题。使用临时文件来存储和管理数据是一种有效的解决方案,可以帮助减少内存占用。 import os import shutil import tempfile from PyQt5.QtWidgets import QApplica…...
后端-实现excel的导出功能(超详细讲解)
首先,不管是一大段文字还是一个几行几列的表格实现方式都是一样的。把动态的内容使用英文单词代替。动态的内容加不加下划线都可以,加了下划线最后生成的表格动态内容部分带有下划线,不加下划线最后生成的表格动态内容部分不带下划线。大家各…...
Docker compose部署portainer
整个工具的代码都在Gitee或者Github地址内 gitee:solomon-parent: 这个项目主要是总结了工作上遇到的问题以及学习一些框架用于整合例如:rabbitMq、reids、Mqtt、S3协议的文件服务器、mongodb github:GitHub - ZeroNing/solomon-parent: 这个项目主要是…...
【游戏引擎之路】登神长阶(十四)——OpenGL教程:士别三日,当刮目相看
【游戏引擎之路】登神长阶(十四)——OpenGL教程:士别三日,当刮目相看 2024年 5月20日-6月4日:攻克2D物理引擎。 2024年 6月4日-6月13日:攻克《3D数学基础》。 2024年 6月13日-6月20日:攻克《3D…...
相等日期问题(c++方法解决)
问题描述 对于一个日期,我们可以计算出年份的各个数位上的数字之和,也可以分别计算月和日的各位数字之和。请问从 1900 年 1 月 1 日至 9999 年 12 月 31 日,总共有多少天,年份的数位数字之和等于月的数位数字之和加日的数位数字之…...
深度学习——优化算法、激活函数、归一化、正则化
文章目录 🌺深度学习面试八股汇总🌺优化算法方法梯度下降 (Gradient Descent, GD)动量法 (Momentum)AdaGrad (Adaptive Gradient Algorithm)RMSProp (Root Mean Square Propagation)Adam (Adaptive Moment Estimation)AdamW 优化算法总结 经验和实践建议…...
Android 老项目适配 Compose 混合开发
在Android项目中使用Jetpack Compose进行混合开发时,可以通过以下步骤进行适配: 1.更新项目的build.gradle文件,确保使用最新的Compose库版本。 dependencies { implementation androidx.compose.ui:ui:<latest_version> implementat…...
PH热榜 | 2024-11-14
DevNow 是一个精简的开源技术博客项目模版,支持 Vercel 一键部署,支持评论、搜索等功能,欢迎大家体验。 [在线预览](https://www.laughingzhu.c 1. Vocera 标语:利用模拟和监控加速语音代理上线 这句话的意思是:通过…...
删库跑路,启动!
起因:这是一个悲伤的故事,在抓logcat时 device待机自动回根目录了,而题主对当前路径的印象还停留在文件夹下,不小心在根目录执行了rm -rf * … 所以,这是个悲伤的故事,东西全没了…device也黑屏了ÿ…...
Vue 3 在现代前端开发中的应用
💓 博客主页:瑕疵的CSDN主页 📝 Gitee主页:瑕疵的gitee主页 ⏩ 文章专栏:《热点资讯》 Vue 3 在现代前端开发中的应用 Vue 3 在现代前端开发中的应用 Vue 3 在现代前端开发中的应用 引言 Vue 3 概述 定义与原理 发展历…...
【HarmonyOS】Hdc server port XXXX has been used.Configure environment variable
【HarmonyOS】Hdc server port XXXX has been used.Configure environment variable 一、 问题背景: 无法调试debug应用,IDE右下角显示该弹窗: Hdc server port XXXX has been used.Configure environment variable ‘OHOS_HDC_SERVER_POR…...
使用 ts-node 运行 ts文件,启动 nodejs项目
最近在写一个nodejs项目,使用 ts-node 启动项目。遇到了一些问题,在此记录一下。 ts-node 是 TypeScript 执行引擎和 Node.js 的 REPL(一个简单的交互式的编程环境)。 它能够直接在 Node.js 上执行 TypeScript,而无需预编译。 这是通过挂接…...
网络六边形受到攻击
大家读完觉得有帮助记得关注和点赞!!! 抽象 现代智能交通系统 (ITS) 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 (…...
SciencePlots——绘制论文中的图片
文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了:一行…...
前端导出带有合并单元格的列表
// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...
优选算法第十二讲:队列 + 宽搜 优先级队列
优选算法第十二讲:队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...
基于Java Swing的电子通讯录设计与实现:附系统托盘功能代码详解
JAVASQL电子通讯录带系统托盘 一、系统概述 本电子通讯录系统采用Java Swing开发桌面应用,结合SQLite数据库实现联系人管理功能,并集成系统托盘功能提升用户体验。系统支持联系人的增删改查、分组管理、搜索过滤等功能,同时可以最小化到系统…...
Java毕业设计:WML信息查询与后端信息发布系统开发
JAVAWML信息查询与后端信息发布系统实现 一、系统概述 本系统基于Java和WML(无线标记语言)技术开发,实现了移动设备上的信息查询与后端信息发布功能。系统采用B/S架构,服务器端使用Java Servlet处理请求,数据库采用MySQL存储信息࿰…...
STM32---外部32.768K晶振(LSE)无法起振问题
晶振是否起振主要就检查两个1、晶振与MCU是否兼容;2、晶振的负载电容是否匹配 目录 一、判断晶振与MCU是否兼容 二、判断负载电容是否匹配 1. 晶振负载电容(CL)与匹配电容(CL1、CL2)的关系 2. 如何选择 CL1 和 CL…...
【Linux系统】Linux环境变量:系统配置的隐形指挥官
。# Linux系列 文章目录 前言一、环境变量的概念二、常见的环境变量三、环境变量特点及其相关指令3.1 环境变量的全局性3.2、环境变量的生命周期 四、环境变量的组织方式五、C语言对环境变量的操作5.1 设置环境变量:setenv5.2 删除环境变量:unsetenv5.3 遍历所有环境…...
用鸿蒙HarmonyOS5实现中国象棋小游戏的过程
下面是一个基于鸿蒙OS (HarmonyOS) 的中国象棋小游戏的实现代码。这个实现使用Java语言和鸿蒙的Ability框架。 1. 项目结构 /src/main/java/com/example/chinesechess/├── MainAbilitySlice.java // 主界面逻辑├── ChessView.java // 游戏视图和逻辑├──…...
书籍“之“字形打印矩阵(8)0609
题目 给定一个矩阵matrix,按照"之"字形的方式打印这个矩阵,例如: 1 2 3 4 5 6 7 8 9 10 11 12 ”之“字形打印的结果为:1,…...
