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的实现方式

  1. 回调函数:在发起异步IO时,传入一个回调函数,在操作完成后执行该回调函数。这种方式在JavaScript中尤为常见,例如Node.js的事件驱动模型。

  2. Future/Promise:Future和Promise是异步编程中的抽象,用于存储异步操作的结果。通过检查Promise的状态,可以判断异步操作是否完成并获取结果。这种模式在Python、Java等语言中也得到了广泛应用。

  3. 事件循环(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 多路复用中,常用的系统调用包括 selectpollepoll

常用的 IO 多路复用方法

  1. select

    • select 是最早实现 IO 多路复用的系统调用,通过一个文件描述符集合来监控多个 IO 通道。

    • 它的调用会阻塞进程,直到一个或多个文件描述符变为就绪(可读、可写或有异常发生),然后程序可以对就绪的文件描述符执行 IO 操作。

    • 缺点在于文件描述符集合的大小有限,且需要遍历所有的文件描述符,性能较低。

  2. poll

    • pollselect 的改进版,没有文件描述符数量限制,解决了 select 的一些不足。

    • poll 通过一个数组而非集合来管理文件描述符,但仍然需要轮询所有文件描述符,且每次调用都需要重新构建文件描述符数组。

    • 随着文件描述符数量增加,poll 的性能会下降。

  3. epoll

    • epoll 是 Linux 下的高效 IO 多路复用方式,针对 selectpoll 的性能问题进行了优化。

    • epoll 的文件描述符不需要重复传递,且支持“边缘触发(edge-triggered)”和“水平触发(level-triggered)”两种模式,能够更高效地检测文件描述符的状态变化。

    • 它适合处理大量并发连接,被广泛用于高并发服务器(如 Nginx、Redis)中。

IO 多路复用的工作流程

  1. 程序创建并注册多个 IO 事件(文件描述符),告诉操作系统哪些事件需要监控。

  2. 操作系统负责检测文件描述符的状态变化,直到某些 IO 事件就绪,然后通知程序。

  3. 程序收到通知后,仅对就绪的 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异步非阻塞

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

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

相关文章

讯飞、阿里云、腾讯云:Android 语音合成服务对比选择

在 移动端 接入语音合成方面,讯飞和腾讯云等都是优秀的选择,但各有其特点和优势。咱们的需求是需要支持普通话/英语/法语三种语言,以下是对各个平台的详细比较: 一、讯飞语音合成介绍 与语音听写相反,语音合成是将一段…

说说软件工程中的“协程”

在软件工程中,协程(coroutine)是一种程序运行的方式,可以理解成“协作的线程”或“协作的函数”。以下是对协程的详细解释: 一、协程的基本概念 定义:协程是一组序列化的子过程,用户能像指挥家…

使用 JavaScript 制作 To-Do List

使用 JavaScript 制作 To-Do List 本文记录了使用 HTML、CSS 和 JavaScript 制作一个简单的 To-Do List 网页的全过程,包含功能描述、代码实现以及优化方向。 **🎉🎉🎉欢迎来到我的博客,我是一名自学了2年半前端的大一学生,熟悉的…

HarmonyOs鸿蒙开发实战(16)=>沉浸式效果第一种方案一窗口全屏布局方案

1.沉浸式效果的目的 开发应用沉浸式效果主要指通过调整状态栏、应用界面和导航条的显示效果来减少状态栏导航条等系统界面的突兀感,从而使用户获得最佳的UI体验。 2.窗口全屏布局方案介绍 调整布局系统为全屏布局,界面元素延伸到状态栏和导航条区域实现沉…

【HarmonyOS】鸿蒙系统在租房项目中的项目实战(一)

从今天开始,博主将开设一门新的专栏用来讲解市面上比较热门的技术 “鸿蒙开发”,对于刚接触这项技术的小伙伴在学习鸿蒙开发之前,有必要先了解一下鸿蒙,从你的角度来讲,你认为什么是鸿蒙呢?它出现的意义又是…

基于STM32的智能语音识别饮水机系统设计

功能描述 1、给饮水机设定称呼,喊出称呼,饮水机回答:我在 2、语音进行加热功能,说:请加热,加热片运行 3、饮水机水位检测,低于阈值播报“水量少,请换水” 4、检测饮水机水温&#xf…

Java 使用MyBatis-Plus数据操作关键字冲突报错You have an error in your SQL syntax问题

问题 这个报错是出现在Java Spring boot项目中,使用MyBatis-Plus通过创建的实体类对数据库的操作过程中,通过实体创建数据库表是没有问题的,而在接口调用服务类操作数据库的时候,会出现报错。报错详情如下: 服务请求异…

高效工具推荐:基于WebGPU的Whisper Web结合内网穿透远程使用指南

文章目录 前言1.本地部署Whisper Web1.1 安装git1.2 安装Node.js1.3 运行项目 2. Whisper Web使用介绍3. 安装Cpolar内网穿透4. 配置公网地址5. 公网访问测试6. 配置固定公网地址 前言 OpenAI开源的 Whisper 语音转文本模型效果都说还不错,今天就给大家推荐 GitHub…

力扣-Mysql-3322- 英超积分榜排名 III(中等)

一、题目来源 3322. 英超积分榜排名 III - 力扣(LeetCode) 二、数据表结构 表:SeasonStats --------------------------- | Column Name | Type | --------------------------- | season_id | int | | team_id …

20241116解决在WIN11和ubuntu20.04通过samba共享时出现局域网千兆带宽拉满的情况

20241116解决在WIN11和ubuntu20.04通过samba共享时出现局域网千兆带宽拉满的情况 2024/11/16 13:42 缘起:最近需要通过iperf3打流,因此在ubuntu20.04服务器上常开sudo nethogs监控流量。 但是发现一个异常,ubuntu20.04服务器上发送的流量过大…

Stable Diffusion最全提示词写法教程

基础书写规则 所有单词都是通过英文书写,单词之间通过, 分割,注意是英文逗号;提示词之间是可以已通过换行书写的,并不会有什么影响;单个提示词的权重是1 , 默认情况下,越往前,权重越大&#xf…

TON商城与Telegram App:生态融合与去中心化未来的精彩碰撞

随着区块链技术的快速发展,去中心化应用(DApp)逐渐成为了数字生态的重要组成部分。而Telegram作为全球领先的即时通讯应用,不仅仅满足于传统的社交功能,更在区块链领域大胆探索,推出了基于其去中心化网络的…

Altenergy电力系统 status_zigbee SQL注入漏洞复现(CVE-2024-11305)

0x01 产品描述: Altenergy‌是一家专注于微型逆变器控制软件的公司,Altenergy电力系统控制软件是Altenergy电力系统公司的一款微型逆变器控制软件。 0x02 漏洞描述: Altenergy电力系统 status_zigbee接口处存在SQL注入漏洞,未经身…

3D Streaming 在线互动展示系统:NVIDIA RTX 4090 加速实时渲染行业数字化转型

随着科技的飞速发展,实时渲染正逐步成为游戏与实时交互领域的重要驱动力。与离线渲染不同,实时渲染需要极高的计算性能,对硬件设备尤其是GPU的性能要求极高。随着 RTX 4090 显卡的问世,其强大的算力和创新技术,为实时渲…

【vmware+ubuntu16.04】vm虚拟机及镜像安装-tools安装包弹不出来问题

学习机器人这门课需要下载虚拟机,做一下记录 首先我下载的是vm虚拟机16, 下载版本可参考该文章课堂上我下载 的镜像是16.04,虚拟机安装教程和镜像添加可参考该博主 按照教程安装成功 安装tools,但是我的弹不出来那个压缩包&…

Figma中文网:UI设计师的新资源宝库

Figma作为在线UI设计工具的先驱,已经在全球范围内被广泛使用,尤其是在中国,它已成为众多设计师的首选。本文将揭秘国内顶尖设计师们与Figma搭配使用的神秘伙伴——即时设计资源广场,这个被称为Figma中文网的平台,究竟有…

小试牛刀-Anchor安装和基础测试

目录 一、编写目的 二、安装步骤 2.1 安装Rust 设置rustup镜像 安装Rust 2.2 安装node.js 2.3 安装Solana-CLI 2.4 安装Anchor CLI 三、Program测试 四、可能出现的问题 Welcome to Code Blocks blog 本篇文章主要介绍了 [Anchor安装和基础测试] 博主广交技术好友&…

【后端】版本控制

版本控制 1. 什么是版本控制? 版本控制(Revision control)是一种在开发的过程中用于管理我们对文件、目录或工程等内容的修改历史,方便查看更改历史记录,备份以便恢复以前的版本的软件工程技术。简单来说就是用于管理…

CC工具箱使用指南:【CAD导出界址点Excel】

一、简介 群友定制工具。 面图层导出界址点Excel表之前已经做过好几个,这个工具则是将CAD导出Excel。 CAD数据如下: 工具将如上截图中的边界线导出界址点Excel,并记录下面内的文字。 二、工具参数介绍 点击【定制工具】组里的【CAD导出界…

python画图|3D errorbars基础教程

【1】引言 前序学习了errorbar()函数的大部分功能,相关文章包括但不限于下述链接: python画图|errorbar初探_python ax.errorbar-CSDN博客 python画图|errorbar()进阶教程- uplims, lolims和xuplims, xlolims应用_ax.errorbar(x, y 0.5, xerrxerr, y…