IO模型种类

文章目录

      • 同步阻塞 I/O(Blocking I/O,BIO)
      • 同步非阻塞 I/O(Non-blocking I/O,NIO)
      • I/O 多路复用(I/O Multiplexing)
      • 信号驱动 I/O(Signal-driven I/O)
      • 异步 I/O(Asynchronous I/O,AIO)

在计算机编程和操作系统领域,I/O(输入/输出)模型是处理输入输出操作的不同方式,主要用于解决应用程序如何与外部设备(如磁盘、网络等)进行数据交互的问题。

同步阻塞 I/O(Blocking I/O,BIO)

  • 工作原理:在这种模型中,当应用程序发起一个 I/O 操作时,会一直阻塞等待,直到该操作完成并返回结果。在此期间,应用程序不能进行其他操作,CPU 资源被闲置。例如,在网络编程中,当调用 recv 函数接收数据时,程序会一直等待,直到有数据到达或者发生错误。
  • 应用场景:适用于连接数比较少且固定的场景,因为它的实现简单,但处理效率较低。比如一些传统的单机应用程序,对并发处理要求不高的场景。
  • 示例代码(Python)
import socketserver_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(('localhost', 8888))
server_socket.listen(1)print('Waiting for a connection...')
conn, addr = server_socket.accept()
print(f'Connected by {addr}')data = conn.recv(1024)  # 阻塞等待数据
print(f'Received: {data.decode()}')conn.sendall(b'Hello, client!')
conn.close()

同步非阻塞 I/O(Non-blocking I/O,NIO)

  • 工作原理:应用程序发起 I/O 操作后,不会阻塞等待结果,而是立即返回。应用程序需要不断地轮询检查 I/O 操作的状态,直到操作完成。这种方式可以让应用程序在等待 I/O 操作的同时进行其他任务,但频繁的轮询会消耗大量的 CPU 资源。
  • 应用场景:适用于连接数较多,但每个连接的 I/O 操作比较少的场景。例如,在一些简单的网络爬虫程序中,可以使用非阻塞 I/O 同时处理多个网络请求。
  • 示例代码(Python)
import socketserver_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(('localhost', 8888))
server_socket.listen(1)
server_socket.setblocking(False)  # 设置为非阻塞模式while True:try:conn, addr = server_socket.accept()print(f'Connected by {addr}')conn.setblocking(False)  # 设置连接为非阻塞模式try:data = conn.recv(1024)if data:print(f'Received: {data.decode()}')conn.sendall(b'Hello, client!')except BlockingIOError:passexcept BlockingIOError:pass

I/O 多路复用(I/O Multiplexing)

  • 工作原理:通过一个机制(如 selectpollepoll 等)同时监视多个 I/O 事件,当其中任何一个 I/O 事件就绪时,通知应用程序进行相应的处理。应用程序在等待期间可以进行其他操作,避免了同步阻塞 I/O 中 CPU 资源的闲置。
  • 应用场景:适用于连接数较多且连接比较活跃的场景,如网络服务器。通过 I/O 多路复用,可以高效地处理大量的并发连接。
  • 示例代码(Python 使用 select
import socket
import selectserver_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(('localhost', 8888))
server_socket.listen(5)inputs = [server_socket]while True:readable, _, _ = select.select(inputs, [], [])for sock in readable:if sock is server_socket:conn, addr = server_socket.accept()print(f'Connected by {addr}')inputs.append(conn)else:data = sock.recv(1024)if data:print(f'Received: {data.decode()}')sock.sendall(b'Hello, client!')else:inputs.remove(sock)sock.close()

信号驱动 I/O(Signal-driven I/O)

  • 工作原理:应用程序发起 I/O 操作后,会立即返回,当 I/O 操作完成时,操作系统会发送一个信号通知应用程序。应用程序在等待信号期间可以进行其他操作。
  • 应用场景:相对较少使用,主要用于一些对实时性要求较高,但对数据传输量要求不高的场景。
  • 示例代码(C 语言):由于信号驱动 I/O 涉及底层系统调用和信号处理,代码较为复杂,以下是一个简单的伪代码示例:
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <signal.h>
#include <unistd.h>// 信号处理函数
void sigio_handler(int signo) {// 处理 I/O 就绪事件printf("I/O is ready!\n");
}int main() {int sockfd;struct sockaddr_in server_addr;// 创建套接字sockfd = socket(AF_INET, SOCK_STREAM, 0);if (sockfd < 0) {perror("socket creation failed");exit(EXIT_FAILURE);}// 设置服务器地址server_addr.sin_family = AF_INET;server_addr.sin_addr.s_addr = INADDR_ANY;server_addr.sin_port = htons(8888);// 绑定套接字if (bind(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {perror("bind failed");exit(EXIT_FAILURE);}// 监听连接if (listen(sockfd, 5) < 0) {perror("listen failed");exit(EXIT_FAILURE);}// 设置信号处理函数signal(SIGIO, sigio_handler);// 设置套接字为信号驱动 I/O 模式fcntl(sockfd, F_SETOWN, getpid());int flags = fcntl(sockfd, F_GETFL);fcntl(sockfd, F_SETFL, flags | O_ASYNC);while (1) {// 可以进行其他操作sleep(1);}return 0;
}

异步 I/O(Asynchronous I/O,AIO)

  • 工作原理:应用程序发起 I/O 操作后,立即返回,继续执行其他任务。操作系统会在 I/O 操作完成后,将结果直接返回给应用程序,而不需要应用程序进行额外的查询或处理。这种方式实现了真正的并发,应用程序的效率最高。
  • 应用场景:适用于对 I/O 性能要求极高的场景,如大型数据库服务器、高性能网络服务器等。
  • 示例代码(Python 使用 asyncio 库模拟异步 I/O)
import asyncioasync def handle_connection(reader, writer):data = await reader.read(1024)message = data.decode()print(f'Received: {message}')writer.write(b'Hello, client!')await writer.drain()writer.close()async def main():server = await asyncio.start_server(handle_connection, 'localhost', 8888)addr = server.sockets[0].getsockname()print(f'Serving on {addr}')async with server:await server.serve_forever()asyncio.run(main())

这些 I/O 模型各有优缺点,在不同的应用场景中可以选择合适的模型来提高程序的性能和效率。

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

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

相关文章

C语言入门教程100讲(40)文件定位

文章目录 1. 什么是文件定位?2. 文件指针3. 文件定位函数3.1 `fseek` 函数3.2 `ftell` 函数3.3 `rewind` 函数4. 示例代码代码解析:输出结果:5. 常见问题问题 1:`fseek` 的 `offset` 参数可以为负数吗?问题 2:如何判断文件定位是否成功?问题 3:`rewind` 和 `fseek(file…

el-table折叠懒加载支持排序

el-table折叠懒加载支持排序 因为el-table懒加载的子节点是通过缓存实现的&#xff0c;如果想在展开的情况下直接刷新对应子节点数据&#xff0c;要操作el-table组件自身数据&#xff0c;否则不会更新 以排序功能为例 maps: new Map() //用于存储子节点懒加载的数据// 加载子…

Off-Road-Freespace-Detection配置pytorch2.0.0

一、概述 在github上进行开源代码搜索&#xff0c;发现了Off-Road-Freespace-Detection&#xff08;链接如下所示&#xff09;。这是对越野环境可通行区域的检测&#xff0c;在经过测试之后&#xff0c;发现对自己有益。 GitHub - chaytonmin/Off-Road-Freespace-Detection: O…

ChatGPT降低论文AIGC重复率的提示词合集(高效降重方法)

&#x1f4a1; 问题&#xff1a;写完毕业论文后&#xff0c;查AIGC率过高&#xff0c;手动降重后仍然很高&#xff0c;该怎么办&#xff1f; &#x1f4cc; 解决方案&#xff1a; 1️⃣ 先查AIGC率&#xff08;找出AI生成的部分&#xff09; 2️⃣ 用ChatGPT优化&#xff08;使…

【Spring 新特性全解析】

Spring 新特性全解析 引言 在当今 Java 企业级开发领域&#xff0c;Spring 框架无疑是中流砥柱般的存在。它以其强大的功能、高度的可扩展性和便捷的开发体验&#xff0c;赢得了广大开发者的青睐。随着技术的不断演进&#xff0c;Spring 也在持续更新迭代&#xff0c;带来了一…

System.arraycopy 在音视频处理中的应用

在音视频开发领域&#xff0c;我们经常需要处理大量的数据&#xff0c;例如音频 PCM 数据的传输、视频帧的缓存等。在这些场景下&#xff0c;数据的复制与传输往往直接影响到应用的性能。Java 提供的 System.arraycopy 方法&#xff0c;在音视频处理代码中出现频率非常高。本文…

fastapi+angular评论和回复

说明&#xff1a;fastapiangular评论和回复 效果图: step1:sql show databases; DROP TABLE users; SHOW CREATE TABLE db_school.users; show tables; use db_school; SELECT * FROM db_school.jewelry_categories; CREATE DATABASE db_school; select *from users -- 用户…

C++11QT复习 (三)

文章目录 [toc]Day5-2 文件IO&#xff08;2025.03.24&#xff09;1. 缓冲区与刷新1.1 常见的缓冲刷新方式 2. 文件读写操作2.1 读取文件2.2 写入文件2.3 追加模式写入2.3 完整代码 3. 文件定位操作4. 字符串IO5. 配置文件解析示例6. 完整代码7. 二进制文件操作总结 Day5-2 文件…

Redis Sentinel 详解

Redis Sentinel 详解 1. 什么是 Redis Sentinel&#xff1f;有什么用&#xff1f; Redis Sentinel&#xff08;哨兵&#xff09; 是 Redis 官方提供的高可用性解决方案&#xff0c;主要用于监控、通知和自动故障转移。当 Redis 主节点&#xff08;master&#xff09;发生故障…

AI日报 - 2025年3月25日

&#x1f31f; 今日概览&#xff08;60秒速览&#xff09; ▎&#x1f916; AGI突破 | Nebula&#xff08;Google Gemini 2.0 Pro&#xff09;破解复杂数学谜题 编码与推理能力再上新台阶 ▎&#x1f4bc; 商业动向 | Sesame AI开源10亿参数语音模型CSM-1B 语音AI进入普惠时代 …

AI医疗革命:英伟达GTC 2025医疗健康与生命科学会议全分析

AI医疗革命:英伟达GTC 2025医疗健康与生命科学会议全分析 一、GTC 2025:AI 医疗的算力与生态双突破 1.1 黄仁勋演讲核心:从训练到推理的代际跨越 在科技界瞩目的英伟达 GTC 2025 大会上,英伟达 CEO 黄仁勋的主题演讲成为全场焦点,为 AI 医疗领域带来了极具变革性的消息。…

【机器学习/大模型/八股文 面经 (一)】

1. PPO算法中使用GAE的好处以及参数γ和λ的作用是什么? 参考答案: GAE(Generalized Advantage Estimation) 的优势在于通过指数加权多步TD误差,平衡优势估计的偏差与方差,提升策略优化的稳定性。γ(折扣因子):控制未来奖励的衰减程度,值越大表示更关注长期收益。λ…

03 Python 基础:数据类型、运算符与流程控制解析

文章目录 一、数据类型 内置的六大类数字类型整数类型 int浮点数 float布尔 bool字符串 str 变量命名 二、数字类型的相互转换显式类型的转换整数&#xff0c;浮点数&#xff0c;复数 之间的显式转换 隐式类型的转换 三、标识符算术运算符比较运算符逻辑运算符位运算符赋值运算…

视频知识库初步设想

将视频字幕提取出来作为知识库来源定位,下一步设想:把视频上的图片信息也精简出来作为定位。 下面是测试例子: 入参: {"model":"deepseek-ai/DeepSeek-R1-Distill-Llama-8B","messages":[{"role":"system","cont…

数据库原理13

1.关系模式设计不当引起的问题&#xff1a;数据冗余&#xff1b;更新异常&#xff1b;插入异常&#xff1b;删除异常 2.外码可以是单个属性&#xff0c;也可以是属性组 3.动态SQL是SQL标准提供的一种语句运行机制 4.若一个模式分解保持函数依赖&#xff0c;则该分解一定具有…

初级:异常处理面试题深度解析

一、引言 在Java开发中&#xff0c;异常处理是确保程序健壮性和稳定性的重要机制。面试官通过相关问题考察候选人对异常处理的理解和运用能力&#xff0c;以及在实际开发中处理异常的经验。本文将深入剖析常见的异常处理面试题&#xff0c;结合实际开发场景&#xff0c;帮助读…

Apache Spark - 用于大规模数据分析的统一引擎

Apache Spark - 用于大规模数据分析的统一引擎 下载运行示例和 Shell使用 Spark Connect 在 Anywhere 上运行 Spark 客户端应用程序 在集群上启动从这里去哪里使用 Spark Shell 进行交互式分析基本有关数据集作的更多信息缓存 自包含应用程序从这里去哪里 Apache Spark 是用于大…

餐饮管理系统的设计与实现(代码+数据库+LW)

摘 要 互联网发展至今&#xff0c;无论是其理论还是技术都已经成熟&#xff0c;而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播&#xff0c;搭配信息管理工具可以很好地为人们提供服务。针对信息管理混乱&#xff0c;出错率高&#xff0c;信息安全性差&#…

【C#】Winform调用NModbus实现Modbus TCP 主站通讯

一、前言 Modbus是一种串行通信协议&#xff0c;是工业领域全球最流行的协议之一。 1.1 环境 系统&#xff1a;Win11 工具&#xff1a;Visual Studio 2022 .Net 版本&#xff1a;.Net Framework4.6.0 依赖库&#xff1a;NModbus 3.0.81 1.2 协议类型 Modbus RTU&#xff1a;一…

【leetcode题解】贪心算法

目录 贪心算法 柠檬水找零 将数组和减半的最少操作次数 最大数 摆动序列 最长递增子序列 递增的三元子序列 最长连续递增序列 买卖股票的最佳时机 买卖股票的最佳时机 II K 次取反后最大化的数组和 按身高排序 优势洗牌 最长回文串 增减字符串匹配 分发饼干 最…