IO(Input/Output)

server/2025/3/27 11:52:13/

IO

IO,即输入/输出,磁盘IO,网络IO

计算机角度的IO

主观意思就是计算机输入输出,计算机是主体。计算机分为5个部分:运算器,控制器,存储器,输入设备,输出设备。

 输入设备:向计算机输入数据和信息的设备,键盘,鼠标都属于输入设备;

输出设备:计算机硬件系统的终端设备,用于接收计算机数据的输出显示,一般显示器、打印机都属于输出设备。

操作系统角度的IO

要将内存中的数据写入磁盘时,那么主体就是一个程序,操作系统负责计算机的资源管理和进程调度我们电脑上运行的应用程序,其实就是需要经过操作系统,才能做一些特殊操作,像磁盘文件的读写内存的读写等。

整整意义上的IO是在操作系统执行的,即应用程序的IO操作氛围两种动作:IO调用和IO执行。IO调用是由进程(应用程序运行态)发起的,而IO执行是操作系统内核的工作。

应用程序发起一次IO的操作流程:

IO调用:应用程序进程向操作系统内核发起调用

IO执行:操作系统内核完成IO操作

  • 内核(Kernel):操作系统核心,管理硬件资源和 IO 操作。

  • 用户空间(User Space):应用程序运行的内存区域,通过系统调用与内核交互。

  • 缓冲区(Buffer):临时存储数据的内存区域,减少直接操作设备的次数。

IO模型 

阻塞IO(Blocking IO)

        用户线程发起 IO 操作后被阻塞,直到数据就绪并完成拷贝。

        缺点如果内核数据一直没准备好,那用户进程将一直阻塞,浪费性能

                   (线程长时间阻塞,资源利用率低)

  • 流程

    1. 用户线程调用 read()

    2. 内核等待数据就绪(如网络包到达)。

    3. 数据从内核空间拷贝到用户空间。

    4. 用户线程恢复执行。

非阻塞IO(Non-blocking IO)

        户线程轮询检查数据是否就绪,未就绪时立即返回错误.

        缺点:频繁轮询消耗 CPU

  • 流程

    1. 用户线程调用 read(),若数据未就绪,内核返回 EWOULDBLOCK

    2. 线程继续执行其他任务,定期重试。

    3. 数据就绪后,完成拷贝。

IO多路复用(IO Multiplexing)

        特点:通过 Selector 监控多个 IO 通道,仅当某通道数据就绪时通知线程处理。

        实现机制系统给我们提供一类函数(如 select、poll、epoll), 它们可以同时监控多个 fd的操作,任何一个返回内核数据就绪,应用进程再发 起 recvfrom()系统调用。

        select/poll(轮询)、epoll(事件驱动,Linux 高效实现)。

select

应用进程通过调用select函数,同时监控多个fd,只要有一个数据状态准备就绪,select函数就会返回可读状态,这时应用进程再发起recvfrom()请求去读取数据

文件描述符 fd(File Descriptor):用来表示相关文件信息
  • 流程

    1. 注册多个通道到 Selector。

    2. Selector 阻塞等待至少一个通道就绪。

    3. 处理就绪通道的 IO 操作。

select 的 IO 多路复用模型,只需要发起一次询问就够了,大大优化了性能。 

缺点:监听的最大连接数有限,在 Linux 系统上一般为 1024kb,select 函数返回后,是通过遍历 fdset,找到就绪的描述符 fd。

因为存在大量遍历,所以会有连接数限制,后面提出poll,与select相比,解决了连接数限制问题,但是同样需要遍历FD,如果就绪fd很少,连接数又很大,那么效率就会线性下降。

epoll

为解决select/poll存在的问题,epoll诞生,它采用时间驱动来实现,

epoll通过epoll_ctl()来注册一个fd,一旦基于某个fd就绪,内核就会采用回调机制,迅速激活这个fd,当进程调用epolll_wait()时便能得到通知,这里去掉了遍历fdset的操作,而是采用监听事件回调的机制。

特性selectpollepoll
实现机制轮询遍历所有 fd轮询遍历所有 fd事件驱动(回调通知就绪 fd)
数据结构位数组(fd_set链表(pollfd结构体数组)红黑树 + 就绪链表
最大 fd 数量1024(受 FD_SETSIZE 限制)无限制(由系统资源决定)无限制(由系统资源决定)
时间复杂度O(n)O(n)O(1)(仅处理就绪 fd)
内存拷贝开销每次调用需拷贝 fd 集合到内核同 select首次注册后,内核维护 fd 集合无需拷贝

异步 IO(AIO asynchronous IO) 

        用户线程发起 IO 操作后立即返回,内核完成数据拷贝后通知线程

  • 流程

    1. 用户线程调用 aio_read()

    2. 内核负责等待数据就绪并拷贝到用户空间。

    3. 内核通过回调或信号通知线程处理数据。

  • 优点:真正异步,无任何阻塞。

 一个场景理解BIO,NIO,AIO

        A,B,C三人去窗口排队买饭,

        BIO:A一直在排队,直到排到自己。

        NIO:B一边玩游戏一边排队,玩一会瞅一下是不是到自己了,直至排到自己。

        AIO:C直接告诉老板,好了叫一下我。

JAVA IO 

阻塞 IO(Blocking I/O BIO)

服务器为每一个链接建立一个线程,由该线程单独负责处理一个客户请求。

  • 特点:每个连接对应一个线程,线程阻塞等待 IO。

  • 适用场景:低并发、简单应用。

  • java">// 服务端
    ServerSocket server = new ServerSocket(8080);
    while (true) {Socket client = server.accept(); // 阻塞new Thread(() -> handle(client)).start();
    }

非阻塞IO( non-blocking IO NIO)

NIO 支持面向缓冲区的、基于通道的 IO 操作。

核心思想: NIO 中非阻塞 I/O 调用不会被阻塞,核心是注册感兴趣的特定 I/O 事件,如可读数据到达,新的套接字连接等等,在发生特定事件时,系统再通知我们,NIO 中实现非阻塞 I/O 的核心对象就是 Selector.

  • 核心类ChannelBufferSelector

  • 适用场景:高并发网络服务。

  • 当有读或写等任何注册的事件发生时,可以从 Selector 中获
    得相应的 SelectionKey,同时从 SelectionKey 中可以找到发生的事件和该事
    件所发生的具体的 SelectableChannel,以获得客户端发送过来的数据。
非阻塞指的是 IO 事件本身不阻塞,但是获取 IO 事件的 select()方法是
需要阻塞等待的.
区别是 BIO 会阻塞在 IO 操作上,NIO 阻塞在事件获取上,没有事件就没有
IO,从高层次看 IO 就不阻塞了.

Channels

通道,与stream不同,stream是单向的,而channels是双向的,就可以读,又可以写。

所有数据都通过 Buffer 对象来处理。你永远不会将字节直接写入通道中,相反,您是将数据写入包含一 个或者多个字节的缓冲区。同样,您不会直接从通道中读取字节,而是将数据从 通道读入缓冲区,再从缓冲区获取这个字节。

 

NIO 中的 Channel 的主要实现有:
FileChannel:从文件中读写数据
DatagramChannel:通过 UDP 读写网络中的数据
SocketChannel:通过 TCP 读写网络中的数据
ServerSocketChannel:可以监听新进来的 TCP 连接
常用方法:
流对象.getChannel(); 通过流对象获得管道
read(byteBuffer); 将数据导入缓存数组
write(byteBuffer); 将数据从缓存数组写出

Buffers

缓冲区本质上是一块可以写入数据,然后可以从中读取数据的内存,这块内存被包装成 NIO Buffer 对象,并提供了一组方法,用来方便的访问该块内存。
对数据的读取/写入需要使用 buffer,buffer 本质就是一个数组

常用方法:

ByteBuffer.allocate(1024); 创建字节数据
byteBuffer.flip(); 翻转这个缓冲区,读操作前使用
byteBuffer.clear(); 清除缓存,写操作前使用
java">    public static void main(String[] args) throws IOException {//输入文件FileInputStream in = new FileInputStream("D:/source.txt");//输出文件FileOutputStream out = new FileOutputStream("D:/dest.txt");//创建通道FileChannel  inchannel =  in.getChannel();FileChannel  outchannel =  out.getChannel();//创建缓冲区ByteBuffer byteBuffer = ByteBuffer.allocate(1024);while(inchannel.read(byteBuffer)!=-1){//切换读,保护已写数据byteBuffer.flip();//写入outchannel.write(byteBuffer);//切换写byteBuffer.clear();}}

Selectors 

用于检查一 个或多个 NIO Channel(通道)的状态是否处于可读、可写。如此可以实现单线程管理多个 channels,也就是可以管理多个网络链接
优点:使用更少的线程来就可以来处理通道了,避免了线程上下文切换带来的开销

 异步 IO(AIO asynchronous IO) 

基于回调机制Future模式,允许应用程序在 I/O 操作完成后通过事件通知处理结果,无需阻塞线程

核心思想:将 I/O 操作的发起与完成解耦,主线程仅发起 I/O 请求,内核或后台线程负责完成实际的数据传输并通知结果。

异步流程(以文件读取为例)
  1. 发起异步操作:调用 read() 方法,传入 CompletionHandler

  2. 内核执行 I/O:数据从磁盘读取到内核缓冲区

  3. 数据拷贝:内核将数据拷贝到用户空间缓冲区。

  4. 回调通知:通过 CompletionHandler 的 completed() 或 failed() 通知结果。


http://www.ppmy.cn/server/176883.html

相关文章

网络爬虫【爬虫库request】

我叫不三不四,很高兴见到大家,欢迎一起学习交流和进步 今天来讲一讲爬虫 Requests是Python的一个很实用的HTTP客户端库,完全满足如今网络爬虫的需求。与Urllib对比,Requests不仅具备Urllib的全部功能;在开发使用上&…

Python----计算机视觉处理(Opencv:图像缩放)

图像缩放 与图像旋转里的缩放的原理一样,图像缩放的原理也是根据需要将原图像的像素数量增加或减少,并通 过插值算法来计算新像素的像素值。 导入模块 import cv2 输入图像 imgcv2.imread(lena.png) 图像缩放 img_sizecv2.resize(img,None,fx0.5,fy0.5,…

Oracle+11g+笔记(11)-数据库的安全管理

Oracle11g笔记(11)-数据库的安全管理 11、数据库的安全管理 11. 1 用户管理 11.1.1 创建用户 创建用户可以采用CREATE USER命令来完成。下面是CREATE USER 命令的语法。 CREATE USER username IDENTIFIED BY password OR IDENTIFIED EXTERNALLY OR IDENTIFIED GLOBALLY AS…

前端面试:[React] useRef 是如何实现的?

useRef 是 React 中一个非常有用的 Hook,它用于在组件中持久存储可变的值而不会引起重新渲染。理解 useRef 的实现原理对于更高效地使用它非常重要。以下是 useRef 的实现原理和使用场景的详细说明。 一、useRef Hook 的基本概念 持久引用:useRef 返回…

VSCode C/C++ 开发环境完整配置及常见问题

要在 Visual Studio Code (VSCode) 中进行 C/C 开发,你需要配置一个强大的开发环境,包括安装必要的扩展、配置编译器和调试器。以下是如何完成这一配置的详细步骤,以及一些常见问题的解决方法。 1. 安装 VSCode 首先,确保你已安装…

OPPO手机怎么更改照片天空?照片换天空软件推荐

在摄影的世界里,天空常常是照片中最引人注目的部分之一。 无论是湛蓝的天空、绚丽的晚霞,还是阴沉的乌云,天空的色彩和氛围都能极大地影响照片的整体效果。如果你对OPPO手机拍摄的照片中的天空不满意,别担心,OPPO手机…

汇川EASY系列之以太网通讯(MODBUS_TCP做主站)

汇川Easy系列以太网通讯中(MODBUSTCP,plc做主站),终于可以不用使用指令就可以完成了,全程通过简单的配置就可通讯。本文将通过EASY系列PLC与调试助手之间完成此操作。具体演示如下; 关于主站和从站的介绍 A/请求:即主动方 向被动方发送的一个要求的信息。 B/主站:发…

postgresql 高版本pgsql备份在低版本pgsql中恢复失败,报错:“unsupported version”

关键字 PostgreSQL、pg_restore、版本兼容性、数据库迁移、pg_dump、备份恢复、unsupported version in file header 背景环境 系统配置 环境类型操作系统PostgreSQL版本内存工具链测试环境Windows 111616GBNavicat/PgAdmin生产环境Windows Server 2012 R2128GBPgAdmin/命令…