操作系统 IO 相关知识
操作系统 IO 相关知识
- 阻塞与非阻塞
- 同步与异步
- IO 和系统调用
- 传统的 IO
- DMA
- mmap 内存映射
- sendfile
- splice
- 常用的 IO 模型
- BIO:同步阻塞 IO
- NIO:同步非阻塞 IO
- IO 多路复用
- 信号驱动 IO
- AIO:异步 IO 模型
IO 就是计算机内部与外部进行数据传输的过程,比如网络 IO 与磁盘 IO
所有 IO 都需要系统调用,由操作系统代理执行,并经历从 IO 设备拷贝到内核空间拷到用户空间的环节
在内核收到调用请求之后,会有数据准备、数据就绪、数据拷贝的阶段
每一个程序员面试的时候或多或少都会被问到相关知识,了解一下相关概念是非常重要的
阻塞与非阻塞
阻塞与非阻塞指线程在等待调用结果(数据,消息,返回值)时的状态
阻塞是指应用线程等待结果时会被挂起,等待内核(或者 IO)完成操作,实际上,内核所做的事情是将 CPU 时间切换给其他有需要的线程,网络应用程序在这种情况下是得不到 CPU 时间做该做的事情的,它会在那里睡觉。因此这里的阻塞应当理解成线程被其他线程阻塞,或者等待 IO 资源结果的时候阻塞
非阻塞是指该线程等待结果(数据准备)时可以执行其他操作,只有在拷贝数据的时候才会阻塞。此时该线程可以做一些其他的 CPU 计算,但是一般会伴随不停的访问请求结果这一操作
注意,阻塞与非阻塞的概念只有同步中才有,没有异步阻塞与异步非阻塞的说法,接下来说一下为什么
同步与异步
同步和异步关注的是消息通信机制
同步指发出调用请求后,请求跟随调用结果一起返回
异步指发出请求后,请求或者调用立即返回,在 IO 设备或者其他的机器操作完毕后,通过回调函数或者其他方式返回状态或者数据信息
比如我们使用消息队列来处理某个功能,一般来说发生消息后就不用管之后的操作了,该过程就是异步的。主线程不关心另一个线程怎么样,所以谈不上阻塞非阻塞
IO 和系统调用
所有的 IO 操作都会有系统调用的过程,同时所有的系统 IO 都分为两个阶段:等待就绪和操作。举例来说,读函数,分为等待系统可读和真正的读;同理,写函数分为等待网卡可以写和真正的写
read(file, tmp_buf, len);
write(socket, tmp_buf, len);
需要说明的是等待就绪的阻塞是不使用 CPU 的,是在空等,这期间数据通过网线以电流的方式输入我们的电脑,并且被保存在缓冲区中;而真正的读写操作的阻塞是使用 CPU 的,即 CPU 将数据从缓冲区拷贝到目标位置的过程,这个时候 CPU 真正在干活
传统的 IO
这里使用普通的 read 和 write 命令来展示一下传统 IO 的弊端
- 用户进程通过 read 方法向操作系统发起调用,此时上下文从用户态转向内核态
- DMA 控制器把数据从硬盘(或者套接字的缓冲区)中拷贝到内核读缓冲区
- CPU 把内核读缓冲区数据拷贝到应用缓冲区,然后上下文从内核态转为用户态,read 和数据一起返回
其过程如下图所示:
write 指令:
- 用户进程通过 write 方法发起调用,上下文从用户态转为内核态
- CPU 将应用缓冲区中数据拷贝到 socket 缓冲区
- DMA 控制器把数据从 socket 缓冲区拷贝到网卡,上下文从内核态切换回用户态,write 返回
read 和 write 分别进行了两次内核态用户态切换和两次 CPU 复制操作,在操作系统中这些是可以被优化的
但是优化之前先处理一个问题,我们可以看到数据会先复制到中间的 socket buffer 中,我们很可能有一个问题就是为什么数据不能从磁盘直接复制到用户缓冲区?原因主要在下面两点:
1,权限隔离:操作系统的内核空间和用户空间是严格分离的,以防止恶意程序直接访问系统资源,造成系统不稳定或安全漏洞。内核负责管理硬件资源,包括磁盘读写,而用户空间的应用程序则运行在更高的抽象层次上
2,地址空间不同:内核空间和用户空间拥有各自的虚拟地址空间。用户缓冲区位于用户空间的虚拟地址范围内,而内核在执行I/O操作时使用的是内核缓冲区,这些缓冲区位于内核空间的地址范围内
DMA
DMA 是 Direct Memory Access,直接内存存取
DMA 是直接内存访问技术,他是一块主板上独立的芯片,它专门用来进行内存和 IO 设备的数据传输,他的主要作用是优化数据从磁盘拷贝到缓冲区这一过程
早期计算机中,用户进程需要读取磁盘数据,需要 CPU 中断和 CPU 参与(就是整个数据的传输过程,都要需要 CPU 亲自参与搬运数据的过程,数据会先从磁盘拷贝到 CPU 寄存器,然后再写入对应的缓冲区),因此效率比较低,发起 IO 请求,每次的 IO 中断,都带来 CPU 的上下文切换。 DMA 控制器接管了数据读写请求。并且加快了 IO 拷贝速度,从而减少 CPU 的处理时间
mmap 内存映射
零拷贝技术是优化拷贝次数的技术,以下的技术包括 mmap 都是零拷贝技术的一种
mmap 将用户空间的一段内存区域映射到内核空间,映射成功后,用户对这段内存区域的修改可以直接反映到内核空间,同样,内核空间对这段区域的修改也直接反映用户空间。即将用户空间和内核空间关联起来,例如堆外内存就是 mmap 零拷贝技术
内核缓冲区和应用缓冲区共享,从而减少了从内核缓冲区到用户缓冲区的一次 CPU 拷贝
sendfile
sendfile 方法 IO 数据对用户空间完全不可见,所以只能适用于完全不需要用户空间处理的情况,比如将磁盘中的数据复制到网卡
整个过程发生了两次用户态和内核态的上下文切换和三次拷贝,数据不经过用户区,只在内核态进行复制。简单介绍一下流程,就是数据存在于内核中时,并未被真正复制到 socket 关联的缓冲区内。取而代之的是,只有记录数据位置和长度的描述符被加入到 socket 缓冲区中。DMA 模块将数据直接从内核缓冲区传递给协议引擎,从而消除了遗留的最后一次复制
Linux2.4内核版本之后对 sendfile 做了进一步优化,通过引入新的硬件支持,这个方式叫做 DMA Scatter/Gather 分散/收集功能,将整个过程优化到两次用户态和内核态的上下文切换和两次拷贝
splice
Linux 从2.6.17支持 splice 数据从磁盘读取到 OS 内核缓冲区后,在内核缓冲区直接可将其转成内核空间其他数据 buffer,而不需要拷贝到用户空间,这是不是和 sendfile 有点像?
注意 splice 和 sendfile 的不同,sendfile 是 DMA 硬件设备不支持的情况下将磁盘数据加载到 kernel buffer(内核空间维护的缓存空间)后,需要一次 CPU copy,拷贝到 socket buffer
而 splice 是直接将两个内核空间的 buffer 进行 pipe 管道传输
#include <fcntl.h>
ssize_t splice(int fd_in, loff_t *off_in, int fd_out, loff_t *off_out, size_t len, unsigned int flags);
常用的 IO 模型
BIO:同步阻塞 IO
同步阻塞 IO 模型,该模型用于描述一方发起调用后,阻塞等待另外一方返回的场景,举几个例子:
- 应用程序发起 read 调用后,会一直阻塞,直到在内核把数据拷贝到用户空间
- 用户请求服务器后,一直等待接口返回
- 长连接
NIO:同步非阻塞 IO
同步非阻塞 IO 模型中,该模型用于描述一方发起调用后,虽然等待该请求的结果,但是我们依然执行自己的一些逻辑流程,然后通过什么回调通知或者定时轮训来获取最终结果
在普通的 NIO 中应用程序会一直轮询发起 read 调用(发起调用会降低 CPU 性能),在数据准备的时间中线程不挂起,直到磁盘准备好数据
数据就绪后,实际的 IO 操作会等待数据复制到应用进程的缓冲区中以后才返回
IO 多路复用
java 中的 NIO、Radis 中的单线程、nginx 中的主进程就是 IO 多路复用(使用选择器,缓冲区、通道来实现,通道将用户数据拷贝到缓冲区中,选择器让程序读取缓冲区中数据),IO 多路复用是 NIO 的一种,但是它的好处是可以在同一条阻塞线程上处理多个不同端口的监听
多路 IO 共用一个同步阻塞接口,任意 IO 可操作都可激活 IO 操作,这是对阻塞 IO 的改进。此时阻塞发生在 select/poll 的系统调用上,而不是阻塞在实际的 I/O 系统调用上。IO 多路复用的高级之处在于它能同时等待多个文件描述符,而这些文件描述符(套接字描述符)其中的任意一个进入读就绪状态,select 等函数就可以返回
信号驱动 IO
这是同步 IO 的一种。信号驱动 I/O 与异步 I/O 的区别是从缓冲区获取数据这个步骤的处理,前者收到的通知是可以开始进行复制操作了,在复制完成之前线程处于阻塞状态,所以它仍属于同步 I/O 操作,而后者收到的通知是复制操作已经完成
AIO:异步 IO 模型
异步 IO 是基于事件或者回调机制实现的,也就是应用操作之后会直接返回(发送 read 直接得到结果),不会堵塞在那里。举个例子:
- 用户下单时会立马得到下单结果,但是要等待一段时间后才可以收到下单成功通知
相关文章:

操作系统 IO 相关知识
操作系统 IO 相关知识 阻塞与非阻塞同步与异步IO 和系统调用传统的 IODMAmmap 内存映射sendfilesplice 常用的 IO 模型BIO:同步阻塞 IONIO:同步非阻塞 IOIO 多路复用信号驱动 IOAIO:异步 IO 模型 IO 就是计算机内部与外部进行数据传输的过程&…...
C++_手写share_ptr
以下是一个简化版的 shared_ptr 的实现: #include <iostream> template <typename T> class SimpleSharedPtr { public:// 构造函数explicit SimpleSharedPtr(T* ptr nullptr) : ptr_(ptr), count_(ptr ? new size_t(1) : nullptr) {}// 拷贝构造函数…...

【启明智显方案分享】6.86寸高清显示屏音频效果器解决方案
一、项目概述 本方案旨在设计一款集成6.86寸高清触摸显示屏的音频效果器,通过HMI(Human-Machine Interface)芯片Model 4驱动,实现高清晰度的视觉交互。该设备不仅支持音乐、麦克风及温响音量的精细控制,还内置丰富的预…...

vue设置每次加载页面时展示一个双开门效果
一、首先创建一个双开门的蒙层组件 <!-- DoorOverlay.vue --> <template><div v-if"isVisible" class"door-overlay"><div class"door left-door"></div><div class"door right-door"></div&…...

简单的docker学习 第8章 docker常用服务安装
第8章 常用服务安装 本章主要学习最常用的,也是安装起来稍有些麻烦的 MySQL 与 Redis 两种服务器的Docker 安装。至于其它服务器的 Docker 安装,大家可自行查找资料。只要 MySQL 与 Redis这两类服务器学会了安装,其它服务器的安装基本也不会…...
01、MySQL-DDL(数据定义语言)
目录 1、查询 2、创建 3、修改 4、删除 1、查询 1、查询所有数据库 show databases; 2、查询当前数据库 select database(); 3、查询当前数据库中所有的表(需要先进入这个数据库) use d1; show tables; 4、查询表结构 desc users; 5、查询指定表的建…...

RT-Thread 操作系统 之 线程间同步 IO设备模型
RT-Thread 操作系统 之 线程间同步 IO设备模型 一、线程间同步1.1、信号量1.1.1、信号量结构体1.1.2、信号量的使用和管理1.1.3、信号量同步例程 1.2、互斥量1.2.1、互斥量的使用和管理 1.3、事件集1.3.1、事件集使用和管理方法1.3.2、事件集三个线程同步实例 二、IO设备模型2.…...
力扣leetcode移动0(C++)
给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。 请注意 ,必须在不复制数组的情况下原地对数组进行操作。 示例 1: 输入: nums [0,1,0,3,12] 输出: [1,3,12,0,0]示例 2: 输入: nums [0] 输出: […...
阿里云部署open-webui实现openai代理服务
一、 环境准备 1. 阿里云服务器,ubuntu22系统 2. 外网服务器,linux系统 3. openai API Key 二、实际操作记录(阿里云服务器端) 1. 根据官方文档安装open-webui服务端: 🚀 Getting Started | Open WebUI 1. 如果服务器配置比较低,…...

你的工作环境,选对劳保鞋了吗?守护安全,从脚下开始!
在众多的工作场所中,我们穿梭于不同的工作环境,从繁忙的工厂车间到复杂的建筑工地,再到需要精细操作的实验室……每一步都承载着对安全的期许和对效率的追求。但你是否意识到,脚下那双不起眼的劳保鞋,其实是守护你安全…...

【Linux】编译器gcc/g++ 、程序翻译过程、动静态库
目录 1.gcc/g Linux编译器1.1. gcc与g的安装1.2. gcc与g用法1.2.1.gcc用法1.2.2. g用法 1.3. 程序翻译的过程1.3.1. 前提知识:1.3.2. 预处理(语言种类不变)条件编译用途: 1.3.3. 编译(生成汇编语言)1.3.4. …...

通义灵码-阿里云推出的AI智能编码助手
通义灵码体验地址 标题通义灵码是什么? 通义灵码是由阿里巴巴推出的基于通义大模型的智能编码辅助工具,提供行级/函数级实时续写、自然语言生成代码、单元测试生成、代码注释生成、代码解释、研发智能问答、异常报错排查等能力,并针对阿里云…...

构建智能生态,视频监控/安防监控EasyCVR视频汇聚流媒体技术在智能分析领域的应用
随着5G、AI、物联网(IoT)、云计算等技术的快速发展,万物互联的时代已经到来,全新的行业生态AIoT正在引领一场深刻的变革。在这场变革中,EasyCVR视频流媒体技术以其强大的视频处理、汇聚与融合能力,在智能分…...

LeetCode Hard|【460. LFU 缓存】
力扣题目链接 LFU全称是最不经常使用算法(Least Frequently Used),LFU算法的基本思想和所有的缓存算法一样,一定时期内被访问次数最少的页,在将来被访问到的几率也是最小的。 相较于 LRU 算法,LFU 更加注重…...

积极参与全球能源科技前沿对话,海博思创推动绿色低碳发展
在能源转型与绿色低碳发展的全球浪潮中,国内领先的储能解决方案供应商海博思创以卓越的技术实力和前瞻性的战略眼光,站在了行业变革的前沿。公司不仅在国内外多个重要展会上大放异彩,更通过一系列技术创新与深度合作,为全球能源行…...
[工具]-ffmpeg-笔记
朋友有一个需求,将视频文件转化为音频文件、音频文件获取音频转化为文本文件。 思路:通过ffmpeg转化视频为音频,通过百度ai提供的voice_t_text接口提取语音文本,但是需要将音频分割成1分钟内的pcm编码 ,采样率16000的…...

Android Fragment:详解,结合真实开发场景Navigation
目录 1)Fragment是什么 2)Fragment的应用场景 3)为什么使用Fragment? 4)Fragment如何使用 5)Fragment的生命周期 6)Android开发,建议是多个activity,还是activity结合fragment&…...

JavaWeb中的Servlet
本笔记基于【尚硅谷全新JavaWeb教程,企业主流javaweb技术栈】https://www.bilibili.com/video/BV1UN411x7xe?vd_sourcea91dafe0f846ad7bd19625e392cf76d8总结 Servlet Servlet简介 动态资源和静态资源 静态资源 无需在程序运行时通过代码运行生成的资源,在程序运…...

SpringBoot AOP 简单的权限校验
本篇文章的主要内容是通过AOP切面编程实现简单的权限校验。 书接上回登录与注册功能 我们的用户表里面不是有role(权限)这个字段吗 在JWT令牌的生成中,我们加入了role字段。 那么接下来,我们就可以通过这个字段来实现权限校验。 我这里就很简单&#x…...

Java生成Word->PDF->图片:基于poi-tl 进行word模板渲染
文章目录 引言I Java生成Word、PDF、图片文档获取标签渲染数据生成文档案例II 工具类封装2.1 word 渲染和word 转 pfd2.2 pdf转成一张图片III poi-tl(word模板渲染) 标签简介文本标签{{var}}图片标签表格标签引用标签IV poi-tl提供了类 Configure 来配置常用的设置标签类型前后…...

【WiFi帧结构】
文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成:MAC头部frame bodyFCS,其中MAC是固定格式的,frame body是可变长度。 MAC头部有frame control,duration,address1,address2,addre…...

《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》
在注意力分散、内容高度同质化的时代,情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现,消费者对内容的“有感”程度,正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中࿰…...

IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)
文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...

Linux 内存管理实战精讲:核心原理与面试常考点全解析
Linux 内存管理实战精讲:核心原理与面试常考点全解析 Linux 内核内存管理是系统设计中最复杂但也最核心的模块之一。它不仅支撑着虚拟内存机制、物理内存分配、进程隔离与资源复用,还直接决定系统运行的性能与稳定性。无论你是嵌入式开发者、内核调试工…...

android13 app的触摸问题定位分析流程
一、知识点 一般来说,触摸问题都是app层面出问题,我们可以在ViewRootImpl.java添加log的方式定位;如果是touchableRegion的计算问题,就会相对比较麻烦了,需要通过adb shell dumpsys input > input.log指令,且通过打印堆栈的方式,逐步定位问题,并找到修改方案。 问题…...

MacOS下Homebrew国内镜像加速指南(2025最新国内镜像加速)
macos brew国内镜像加速方法 brew install 加速formula.jws.json下载慢加速 🍺 最新版brew安装慢到怀疑人生?别怕,教你轻松起飞! 最近Homebrew更新至最新版,每次执行 brew 命令时都会自动从官方地址 https://formulae.…...
【学习笔记】erase 删除顺序迭代器后迭代器失效的解决方案
目录 使用 erase 返回值继续迭代使用索引进行遍历 我们知道类似 vector 的顺序迭代器被删除后,迭代器会失效,因为顺序迭代器在内存中是连续存储的,元素删除后,后续元素会前移。 但一些场景中,我们又需要在执行删除操作…...
苹果AI眼镜:从“工具”到“社交姿态”的范式革命——重新定义AI交互入口的未来机会
在2025年的AI硬件浪潮中,苹果AI眼镜(Apple Glasses)正在引发一场关于“人机交互形态”的深度思考。它并非简单地替代AirPods或Apple Watch,而是开辟了一个全新的、日常可接受的AI入口。其核心价值不在于功能的堆叠,而在于如何通过形态设计打破社交壁垒,成为用户“全天佩戴…...
嵌入式常见 CPU 架构
架构类型架构厂商芯片厂商典型芯片特点与应用场景PICRISC (8/16 位)MicrochipMicrochipPIC16F877A、PIC18F4550简化指令集,单周期执行;低功耗、CIP 独立外设;用于家电、小电机控制、安防面板等嵌入式场景8051CISC (8 位)Intel(原始…...

软件工程 期末复习
瀑布模型:计划 螺旋模型:风险低 原型模型: 用户反馈 喷泉模型:代码复用 高内聚 低耦合:模块内部功能紧密 模块之间依赖程度小 高内聚:指的是一个模块内部的功能应该紧密相关。换句话说,一个模块应当只实现单一的功能…...