五种IO模型- 阻塞IO、非阻塞IO、多路复用IO、信号驱动IO以及异步IO
在操作系统中处理输入/输出(IO)操作的过程中,存在多种方式,包括阻塞IO、非阻塞IO、多路复用IO、信号驱动IO以及异步IO。这些方式在操作系统实现和应用程序编写时有着不同的适用场景和性能特征。接下来,我将逐一介绍它们的实现原理、优缺点以及应用场景,同时给出Java和Python的实验示例。
1. 阻塞IO (Blocking IO)
实现原理:
在阻塞IO中,IO操作会导致应用程序被阻塞,直到IO操作完成。这意味着,应用程序在发出IO请求后,需要等到数据完全准备好或者已经被发送完成后才能继续执行其他操作。
优缺点:
- 优点:实现简单,程序逻辑容易理解。
- 缺点:效率低下,因为线程会在IO操作上等待,从而阻塞程序处理其他任务。
应用场景:
适用于简单的、并发性要求不高的场景,如命令行工具、简单的文件读写操作。
Java实验示例:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;public class BlockingIOExample {public static void main(String[] args) throws IOException {Socket socket = new Socket("example.com", 80);BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));String line;// This read operation will block until data is availablewhile ((line = reader.readLine()) != null) {System.out.println(line);}}
}
Python实验示例:
import socketdef blocking_io_example():s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)s.connect(("example.com", 80))s.sendall(b"GET / HTTP/1.0\r\n\r\n")data = s.recv(1024) # This will blockwhile data:print(data.decode())data = s.recv(1024) # This will block againblocking_io_example()
2. 非阻塞IO (Non-blocking IO)
实现原理:
在非阻塞IO中,应用程序在发出IO请求时,如果数据不立即可用,则立即返回而不是阻塞。这可以通过不停地轮询IO设备来检查数据可用性。
优缺点:
- 优点:不需要等待IO操作结束,可以进行其他处理,较少IO等待时间。
- 缺点:可能会导致CPU空转浪费资源,需要通过轮询检查数据可用性。
应用场景:
适合需要快速反应和并发处理的网络服务或GUI应用程序。
Java实验示例:
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.net.InetSocketAddress;public class NonBlockingIOExample {public static void main(String[] args) throws IOException {SocketChannel socketChannel = SocketChannel.open();socketChannel.configureBlocking(false);socketChannel.connect(new InetSocketAddress("example.com", 80));while (!socketChannel.finishConnect()) {// Busy-wait, can perform other tasks}ByteBuffer buffer = ByteBuffer.allocate(1024);int bytesRead = socketChannel.read(buffer); // Non-blocking readwhile (bytesRead != -1) {buffer.flip();while (buffer.hasRemaining()) {System.out.print((char) buffer.get());}buffer.clear();bytesRead = socketChannel.read(buffer); // Non-blocking read}}
}
Python实验示例:
import socket
import selectorsdef non_blocking_io_example():s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)s.setblocking(False)s.connect_ex(("example.com", 80))selector = selectors.DefaultSelector()selector.register(s, selectors.EVENT_WRITE)while True:for key, events in selector.select():sock = key.fileobjif events & selectors.EVENT_WRITE:sock.sendall(b"GET / HTTP/1.0\r\n\r\n")selector.unregister(sock)selector.register(sock, selectors.EVENT_READ)elif events & selectors.EVENT_READ:data = sock.recv(1024)if data:print(data.decode())else:returnnon_blocking_io_example()
3. 多路复用IO (IO Multiplexing)
实现原理:
多路复用IO采用一个或者多个IO接口来监控多个文件描述符,一旦某个文件描述符就绪,应用程序就会得到通知。这可以通过select、poll、epoll等系统调用实现。
优缺点:
- 优点:高效地处理多个IO通道,适合高并发场景。
- 缺点:代码复杂度较高,底层实现与具体平台绑定,可能在短期大量连接时性能下降。
应用场景:
适用于高并发服务器,如Web服务器、聊天服务器。
Java实验示例:
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Iterator;public class MultiplexingIOExample {public static void main(String[] args) throws IOException {Selector selector = Selector.open();SocketChannel socketChannel = SocketChannel.open();socketChannel.configureBlocking(false);socketChannel.connect(new InetSocketAddress("example.com", 80));socketChannel.register(selector, SelectionKey.OP_CONNECT);while (true) {selector.select();Iterator<SelectionKey> keys = selector.selectedKeys().iterator();while (keys.hasNext()) {SelectionKey key = keys.next();keys.remove();if (key.isConnectable()) {SocketChannel sc = (SocketChannel) key.channel();if (sc.finishConnect()) {sc.register(selector, SelectionKey.OP_READ);}} else if (key.isReadable()) {SocketChannel sc = (SocketChannel) key.channel();ByteBuffer buffer = ByteBuffer.allocate(1024);int bytesRead = sc.read(buffer);if (bytesRead > 0) {buffer.flip();while (buffer.hasRemaining()) {System.out.print((char) buffer.get());}} else if (bytesRead == -1) {sc.close();}}}}}
}
Python实验示例:
import socket
import selectorsdef multiplexing_io_example():selector = selectors.DefaultSelector()s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)s.setblocking(False)s.connect_ex(("example.com", 80))selector.register(s, selectors.EVENT_WRITE)while True:events = selector.select()for key, event in events:sock = key.fileobjif event & selectors.EVENT_WRITE:sock.sendall(b"GET / HTTP/1.0\r\n\r\n")selector.modify(sock, selectors.EVENT_READ)elif event & selectors.EVENT_READ:data = sock.recv(1024)if data:print(data.decode())else:selector.unregister(sock)sock.close()returnmultiplexing_io_example()
4. 信号驱动IO (Signal-driven IO)
实现原理:
信号驱动IO主要依赖于信号机制,应用程序可以为某个文件描述符设置某种IO事件的信号处理函数。当事件发生时,内核会通知应用程序。
优缺点:
- 优点:减少轮询开销,与异步IO结合时可以实现更高效的非阻塞操作。
- 缺点:编程复杂度较高,各平台对信号处理支持不一致,信号过多可能影响性能。
应用场景:
适合轻量级IO处理或当频繁通知不成问题时,如消息通知系统。
由于信号驱动IO在Java和Python中实现较为复杂且依赖于底层操作系统特性,因此在这里不提供具体的实验示例。
5. 异步IO (Asynchronous IO)
实现原理:
在异步IO中,应用程序只需发起IO操作,内核负责完成操作并在操作结束后通知应用程序。应用程序在IO操作过程中可以继续执行其他任务,并且不需要等待。
优缺点:
- 优点:效率高,是实现高并发和低延迟的理想方式,通过事件机制可以减少开销。
- 缺点:编程模型和调试复杂,错误处理较为困难。
应用场景:
适用于高性能、高并发服务器,如现代Web服务器、异步网络操作、I/O密集型应用。
Java实验示例 NIO2 from Java 7:
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
import java.net.InetSocketAddress;
import java.util.concurrent.ExecutionException;public class AsynchronousIOExample {public static void main(String[] args) {try {AsynchronousSocketChannel socketChannel = AsynchronousSocketChannel.open();socketChannel.connect(new InetSocketAddress("example.com", 80)).get();ByteBuffer buffer = ByteBuffer.allocate(1024);socketChannel.read(buffer, buffer, new CompletionHandler<Integer, ByteBuffer>() {@Overridepublic void completed(Integer result, ByteBuffer buffer) {buffer.flip();while (buffer.hasRemaining()) {System.out.print((char) buffer.get());}}@Overridepublic void failed(Throwable exc, ByteBuffer buffer) {System.out.println("Failed: " + exc.getMessage());}});} catch (IOException | InterruptedException | ExecutionException e) {e.printStackTrace();}}
}
Python实验示例:
import asyncioasync def async_io_example():reader, writer = await asyncio.open_connection('example.com', 80)writer.write(b"GET / HTTP/1.0\r\n\r\n")await writer.drain()while True:data = await reader.read(1024)if data:print(data.decode())else:breakasyncio.run(async_io_example())
总结不同IO模型的选择,应依赖于具体需求和环境。阻塞IO适合简单任务;非阻塞和多路复用IO适应高并发;信号驱动IO用于轻量级通知场景;而异步IO则用于高性能应用。
相关文章:
五种IO模型- 阻塞IO、非阻塞IO、多路复用IO、信号驱动IO以及异步IO
在操作系统中处理输入/输出(IO)操作的过程中,存在多种方式,包括阻塞IO、非阻塞IO、多路复用IO、信号驱动IO以及异步IO。这些方式在操作系统实现和应用程序编写时有着不同的适用场景和性能特征。接下来,我将逐一介绍它们…...
Vscode GStreamer插件开发环境配置
概述 本教程使用vscode和Docker搭建Gstreamer2.24的开发环境,可以用于开发调试Gstreamer程序或者自定义插件开发。 1. vscode依赖插件 C/C Extension Pack(ms-vscode.cpptools-extension-pack):该插件包包含一组用于 Visual St…...
flask基础
from flask import Flask, requestapp Flask(__name__)# app.route(/) # def hello_world(): # put applications code here # return Hello World!app.route(/) # 路由 当用户访问特定 URL 时,Flask 会调用对应的视图函数来处理请求 def index():return …...
Java日志框架:log4j、log4j2、logback
文章目录 配置文件相关1. properties测试 2. XMl使用Dom4j解析XML Log4j与Log4j2日志门面 一、Log4j1.1 Logges1.2 Appenders1.3 Layouts1.4 使用1.5 配置文件详解1.5.1 配置根目录1.5.2 配置日志信息输出目的地Appender1.5.3 输出格式设置 二、Log4j22.1 XML配置文件解析2.2 使…...
鸿蒙-expandSafeArea使用
应用未使用setWindowLayoutFullScreen()接口设置窗口全屏布局时,默认使能组件安全区布局。可以使用expandSafeArea属性扩展安全区域属性进行调整 扩展安全区域属性原理 布局阶段按照安全区范围大小进行UI元素布局。布局完成后查看设置了expandSafeArea的组件边界&…...
【es6复习笔记】Spread 扩展运算符(8)
在现代前端开发中,JavaScript 的扩展运算符(Spread Operator)是一个非常有用的特性,它允许你将数组或对象展开,以便在函数调用、数组拼接、对象复制等场景中更方便地处理数据。扩展运算符(spread࿰…...
第22天:信息收集-Web应用各语言框架安全组件联动系统数据特征人工分析识别项目
#知识点 1、信息收集-Web应用-开发框架-识别安全 2、信息收集-Web应用-安全组件-特征分析 一、ICO图标: 1、某个应用系统的标示,如若依系统有自己特点的图标;一旦该系统出问题,使用该系统的网站都会受到影响; 2、某个公…...
后端-redis
Redis RedisString类型String类型的常用命令 Hash类型Hash类型的常用命令 List类型List类型的常用命令 Set类型Set类型的常用命令 SortedSet类型SortedSet类型的常用命令 Redis序列化缓存更新策略缓存穿透缓存雪崩缓存击穿 Redis Redis是一个key-value的数据库,key…...
开发场景中Java 集合的最佳选择
在 Java 开发中,集合类是处理数据的核心工具。合理选择集合,不仅可以提高代码效率,还能让代码更简洁。本篇文章将重点探讨 List、Set 和 Map 的适用场景及优缺点,帮助你在实际开发中找到最佳解决方案。 一、List:有序存…...
golangci-lint安装与Goland集成
golangci-lint安装与Goland集成 1.golangci-lint概述2.golangci-lint安装3.Goland 中集成 golangci-lint4.golangci-lint 的使用5.排除代码检查 1.golangci-lint概述 golangci-lint是用于go语言的代码静态检查工具集 官网地址:golangci-lint 特性: 快…...
金仓数据库安装-Kingbase v9-centos
在很多年前有个项目用的金仓数据库,上线稳定后就没在这个项目了,只有公司的开发环境还在维护,已经好多年没有安装过了,重温一下金仓数据库安装,体验一下最新版本,也做一个新版本的试验环境; 一、…...
条款6:auto推导若非己愿,使用显式类型初始化惯用法
一、代理类 所谓的代理类就是以模仿和增强一些类型的行为为目的存在的类 class MyArray { public:class MyArraySize{public:MyArraySize(int size) : theSize(size) {}int size() const { return theSize; }operator int() const { return theSize; }private:int theSize;};…...
蓝桥杯物联网开发板硬件组成
第一节 开发板简介 物联网设计与开发竞赛实训平台由蓝桥杯大赛技术支持单位北京四梯科技有限公司设计和生产,该产品可用于参加蓝桥杯物联网设计与开发赛道的竞赛实训或院校相关课程的 实践教学环节。 开发板基于STM32WLE5无线微控制器设计,芯片提供了25…...
视频汇聚融合云平台Liveweb一站式解决视频资源管理痛点
随着5G技术的广泛应用,各领域都在通信技术加持下通过海量终端设备收集了大量视频、图像等物联网数据,并通过人工智能、大数据、视频监控等技术方式来让我们的世界更安全、更高效。然而,随着数字化建设和生产经营管理活动的长期开展࿰…...
(aaai2025) FD2-Net: Frequency-Driven Feature Decomposition Network
论文:FD2-Net: Frequency-Driven Feature Decomposition Network for Infrared-Visible Object Detection 代码:https://github.com/like413/FD2-Net 这个论文核心思想认为:多源融合目标检测方法忽略了频率上的互补特征,如可见光图…...
深度学习之目标检测——RCNN
Selective Search 背景:事先不知道需要检测哪个类别,且候选目标存在层级关系与尺度关系 常规解决方法:穷举法,在原始图片上进行不同尺度不同大小的滑窗,获取每个可能的位置 弊端:计算量大,且尺度不能兼顾 Selective …...
2014年IMO第3题
在凸四边形 A B C D ABCD ABCD 中, ∠ A B C = ∠ A D C = π 2 \angle ABC=\angle ADC=\frac{\pi}{2} ∠ABC=∠ADC=2π, H H H 为 A A A 在 B D BD BD 上的投影, 在边 A B AB AB 上有一点 S S S, ∠ C H S − ∠ C S B = π 2 \angle CHS-\angle CSB=\frac{\pi}{2} …...
国高材服务 | 高分子结晶动力学表征——高低温热台偏光显微镜
众所周知,聚合物制品的实际使用性能(如光学透明性、硬度、模量等)与材料内部的结晶形态、晶粒大小及完善程度有着密切的联系,因此,对聚合物结晶形态等的研究具有重要的理论和实际意义。 随着结晶条件的不用,…...
跨站请求伪造之基本介绍
一.基本概念 1.定义 跨站请求伪造(Cross - Site Request Forgery,缩写为 CSRF)漏洞是一种网络安全漏洞。它是指攻击者通过诱导用户访问一个恶意网站,利用用户在被信任网站(如银行网站、社交网站等)的登录状…...
Hadoop集群(HDFS集群、YARN集群、MapReduce计算框架)
一、 简介 Hadoop主要在分布式环境下集群机器,获取海量数据的处理能力,实现分布式集群下的大数据存储和计算。 其中三大核心组件: HDFS存储分布式文件存储、YARN分布式资源管理、MapReduce分布式计算。 二、工作原理 2.1 HDFS集群 Web访问地址&…...
IDEA运行Tomcat出现乱码问题解决汇总
最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…...
XML Group端口详解
在XML数据映射过程中,经常需要对数据进行分组聚合操作。例如,当处理包含多个物料明细的XML文件时,可能需要将相同物料号的明细归为一组,或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码,增加了开…...
地震勘探——干扰波识别、井中地震时距曲线特点
目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波:可以用来解决所提出的地质任务的波;干扰波:所有妨碍辨认、追踪有效波的其他波。 地震勘探中,有效波和干扰波是相对的。例如,在反射波…...
Xshell远程连接Kali(默认 | 私钥)Note版
前言:xshell远程连接,私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...
MFC内存泄露
1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...
Linux云原生安全:零信任架构与机密计算
Linux云原生安全:零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言:云原生安全的范式革命 随着云原生技术的普及,安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测,到2025年,零信任架构将成为超…...
sqlserver 根据指定字符 解析拼接字符串
DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...
TRS收益互换:跨境资本流动的金融创新工具与系统化解决方案
一、TRS收益互换的本质与业务逻辑 (一)概念解析 TRS(Total Return Swap)收益互换是一种金融衍生工具,指交易双方约定在未来一定期限内,基于特定资产或指数的表现进行现金流交换的协议。其核心特征包括&am…...
工业自动化时代的精准装配革新:迁移科技3D视觉系统如何重塑机器人定位装配
AI3D视觉的工业赋能者 迁移科技成立于2017年,作为行业领先的3D工业相机及视觉系统供应商,累计完成数亿元融资。其核心技术覆盖硬件设计、算法优化及软件集成,通过稳定、易用、高回报的AI3D视觉系统,为汽车、新能源、金属制造等行…...
OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 在 GPU 上对图像执行 均值漂移滤波(Mean Shift Filtering),用于图像分割或平滑处理。 该函数将输入图像中的…...
