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

五种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接口来监控多个文件描述符,一旦某个文件描述符就绪,应用程序就会得到通知。这可以通过selectpollepoll等系统调用实现。

优缺点:

  • 优点:高效地处理多个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

在操作系统中处理输入/输出&#xff08;IO&#xff09;操作的过程中&#xff0c;存在多种方式&#xff0c;包括阻塞IO、非阻塞IO、多路复用IO、信号驱动IO以及异步IO。这些方式在操作系统实现和应用程序编写时有着不同的适用场景和性能特征。接下来&#xff0c;我将逐一介绍它们…...

Vscode GStreamer插件开发环境配置

概述 本教程使用vscode和Docker搭建Gstreamer2.24的开发环境&#xff0c;可以用于开发调试Gstreamer程序或者自定义插件开发。 1. vscode依赖插件 C/C Extension Pack&#xff08;ms-vscode.cpptools-extension-pack&#xff09;&#xff1a;该插件包包含一组用于 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 时&#xff0c;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()接口设置窗口全屏布局时&#xff0c;默认使能组件安全区布局。可以使用expandSafeArea属性扩展安全区域属性进行调整 扩展安全区域属性原理 布局阶段按照安全区范围大小进行UI元素布局。布局完成后查看设置了expandSafeArea的组件边界&…...

【es6复习笔记】Spread 扩展运算符(8)

在现代前端开发中&#xff0c;JavaScript 的扩展运算符&#xff08;Spread Operator&#xff09;是一个非常有用的特性&#xff0c;它允许你将数组或对象展开&#xff0c;以便在函数调用、数组拼接、对象复制等场景中更方便地处理数据。扩展运算符&#xff08;spread&#xff0…...

第22天:信息收集-Web应用各语言框架安全组件联动系统数据特征人工分析识别项目

#知识点 1、信息收集-Web应用-开发框架-识别安全 2、信息收集-Web应用-安全组件-特征分析 一、ICO图标&#xff1a; 1、某个应用系统的标示&#xff0c;如若依系统有自己特点的图标&#xff1b;一旦该系统出问题&#xff0c;使用该系统的网站都会受到影响&#xff1b; 2、某个公…...

后端-redis

Redis RedisString类型String类型的常用命令 Hash类型Hash类型的常用命令 List类型List类型的常用命令 Set类型Set类型的常用命令 SortedSet类型SortedSet类型的常用命令 Redis序列化缓存更新策略缓存穿透缓存雪崩缓存击穿 Redis Redis是一个key-value的数据库&#xff0c;key…...

开发场景中Java 集合的最佳选择

在 Java 开发中&#xff0c;集合类是处理数据的核心工具。合理选择集合&#xff0c;不仅可以提高代码效率&#xff0c;还能让代码更简洁。本篇文章将重点探讨 List、Set 和 Map 的适用场景及优缺点&#xff0c;帮助你在实际开发中找到最佳解决方案。 一、List&#xff1a;有序存…...

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语言的代码静态检查工具集 官网地址&#xff1a;golangci-lint 特性&#xff1a; 快…...

金仓数据库安装-Kingbase v9-centos

在很多年前有个项目用的金仓数据库&#xff0c;上线稳定后就没在这个项目了&#xff0c;只有公司的开发环境还在维护&#xff0c;已经好多年没有安装过了&#xff0c;重温一下金仓数据库安装&#xff0c;体验一下最新版本&#xff0c;也做一个新版本的试验环境&#xff1b; 一、…...

条款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;};…...

蓝桥杯物联网开发板硬件组成

第一节 开发板简介 物联网设计与开发竞赛实训平台由蓝桥杯大赛技术支持单位北京四梯科技有限公司设计和生产&#xff0c;该产品可用于参加蓝桥杯物联网设计与开发赛道的竞赛实训或院校相关课程的 实践教学环节。 开发板基于STM32WLE5无线微控制器设计&#xff0c;芯片提供了25…...

视频汇聚融合云平台Liveweb一站式解决视频资源管理痛点

随着5G技术的广泛应用&#xff0c;各领域都在通信技术加持下通过海量终端设备收集了大量视频、图像等物联网数据&#xff0c;并通过人工智能、大数据、视频监控等技术方式来让我们的世界更安全、更高效。然而&#xff0c;随着数字化建设和生产经营管理活动的长期开展&#xff0…...

(aaai2025) FD2-Net: Frequency-Driven Feature Decomposition Network

论文&#xff1a;FD2-Net: Frequency-Driven Feature Decomposition Network for Infrared-Visible Object Detection 代码&#xff1a;https://github.com/like413/FD2-Net 这个论文核心思想认为&#xff1a;多源融合目标检测方法忽略了频率上的互补特征&#xff0c;如可见光图…...

深度学习之目标检测——RCNN

Selective Search 背景:事先不知道需要检测哪个类别,且候选目标存在层级关系与尺度关系 常规解决方法&#xff1a;穷举法&#xff0c;在原始图片上进行不同尺度不同大小的滑窗&#xff0c;获取每个可能的位置 弊端&#xff1a;计算量大&#xff0c;且尺度不能兼顾 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} …...

国高材服务 | 高分子结晶动力学表征——高低温热台偏光显微镜

众所周知&#xff0c;聚合物制品的实际使用性能&#xff08;如光学透明性、硬度、模量等&#xff09;与材料内部的结晶形态、晶粒大小及完善程度有着密切的联系&#xff0c;因此&#xff0c;对聚合物结晶形态等的研究具有重要的理论和实际意义。 随着结晶条件的不用&#xff0c…...

跨站请求伪造之基本介绍

一.基本概念 1.定义 跨站请求伪造&#xff08;Cross - Site Request Forgery&#xff0c;缩写为 CSRF&#xff09;漏洞是一种网络安全漏洞。它是指攻击者通过诱导用户访问一个恶意网站&#xff0c;利用用户在被信任网站&#xff08;如银行网站、社交网站等&#xff09;的登录状…...

Hadoop集群(HDFS集群、YARN集群、MapReduce​计算框架)

一、 简介 Hadoop主要在分布式环境下集群机器&#xff0c;获取海量数据的处理能力&#xff0c;实现分布式集群下的大数据存储和计算。 其中三大核心组件: HDFS存储分布式文件存储、YARN分布式资源管理、MapReduce分布式计算。 二、工作原理 2.1 HDFS集群 Web访问地址&…...

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...

超短脉冲激光自聚焦效应

前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应&#xff0c;这是一种非线性光学现象&#xff0c;主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场&#xff0c;对材料产生非线性响应&#xff0c;可能…...

突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合

强化学习&#xff08;Reinforcement Learning, RL&#xff09;是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程&#xff0c;然后使用强化学习的Actor-Critic机制&#xff08;中文译作“知行互动”机制&#xff09;&#xff0c;逐步迭代求解…...

安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件

在选煤厂、化工厂、钢铁厂等过程生产型企业&#xff0c;其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进&#xff0c;需提前预防假检、错检、漏检&#xff0c;推动智慧生产运维系统数据的流动和现场赋能应用。同时&#xff0c;…...

可靠性+灵活性:电力载波技术在楼宇自控中的核心价值

可靠性灵活性&#xff1a;电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中&#xff0c;电力载波技术&#xff08;PLC&#xff09;凭借其独特的优势&#xff0c;正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据&#xff0c;无需额外布…...

uniapp中使用aixos 报错

问题&#xff1a; 在uniapp中使用aixos&#xff0c;运行后报如下错误&#xff1a; AxiosError: There is no suitable adapter to dispatch the request since : - adapter xhr is not supported by the environment - adapter http is not available in the build 解决方案&…...

分布式增量爬虫实现方案

之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面&#xff0c;避免重复抓取&#xff0c;以节省资源和时间。 在分布式环境下&#xff0c;增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路&#xff1a;将增量判…...

Java + Spring Boot + Mybatis 实现批量插入

在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法&#xff1a;使用 MyBatis 的 <foreach> 标签和批处理模式&#xff08;ExecutorType.BATCH&#xff09;。 方法一&#xff1a;使用 XML 的 <foreach> 标签&#xff…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...

Python+ZeroMQ实战:智能车辆状态监控与模拟模式自动切换

目录 关键点 技术实现1 技术实现2 摘要&#xff1a; 本文将介绍如何利用Python和ZeroMQ消息队列构建一个智能车辆状态监控系统。系统能够根据时间策略自动切换驾驶模式&#xff08;自动驾驶、人工驾驶、远程驾驶、主动安全&#xff09;&#xff0c;并通过实时消息推送更新车…...