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

【Linux】【文件】读文件的IO操作

【Linux】【文件】读文件的IO操作

1当进程想要读取磁盘的某个文件时会通过read()函数 发起读取
2用户态切换到内核态 并根据系统调用发起软中断阻塞线程
3.内核先查询page cache查看是否存在
4不存在内核会发起io请求 将io请求通过submit_bio 生成bio 合成request请求
5 将request请求交给块设备层 放在plug请求队列中 并在合适条件下放入电梯队列
6 满足执行条件后向块设备驱动程序下发任务放入dispatch队列等待执行
7 执行完成后发起硬中断

1. 用户态发起读取请求

应用程序使用 read() 系统调用请求读取磁盘上的文件。

2. 用户态切换到内核态

系统调用触发内核工作,将控制权从用户态交给内核态。
软中断(software interrupt)用于实现这种上下文切换。
如果数据不在内存中(即没有缓存),线程会被阻塞,直到数据被读取到内存。

3. 查询 Page Cache

首先检查 Page Cache 是否已有目标数据。
命中(数据已在 Page Cache 中)直接将数据从缓存复制到用户进程的缓冲区。操作完成,返回读取字节数。
未命中(数据不在 Page Cache 中):内核需要从磁盘读取数据。

4. 发起 IO 请求

如果目标数据不在 Page Cache 中,内核将发起磁盘 IO 请求。
内核调用 submit_bio() 方法,生成 bio 数据结构,表示 IO 操作的基本单元(如读或写操作)。
bio 包含:操作类型(如读取)。目标磁盘扇区信息。数据存储的缓冲区。
Request 合成:bio 被进一步包装为 request,表示完整的 IO 请求。

5. 进入块设备层

内核会暂时将 IO 请求存储在一个短暂的 Plug 请求队列 中。在合适时机(如队列满或需要强制提交时)将请求批量提交到电梯队列。(电梯算法对 IO 请求进行排序和优化,以减少磁盘寻道时间。)

6. 块设备驱动程序

电梯队列中的请求在条件满足时被下发到 块设备驱动程序。
驱动程序将请求存储在 Dispatch 队列中,等待磁盘设备处理。

7. 硬件执行和完成通知

磁盘完成数据读取后(存在磁盘缓存)数据从磁盘通过 DMA 控制器 直接传输到内存的指定位置(通常是内核缓冲区或 Page Cache),而不需要 CPU 的干预,通过 硬中断 通知内核操作完成。
中断触发后:将数据写入 Page Cache。唤醒之前阻塞的线程。

8. 数据返回用户态

内核将读取的数据从 Page Cache 复制到用户进程缓冲区。
用户态的 read() 调用返回,读取操作完成。


http://www.kler.cn/a/505248.html

相关文章:

  • docker swarm 部署问题 和 指定节点部署服务
  • 《零基础Go语言算法实战》【题目 2-30】并发安全问题
  • Oracle EBS GL定期盘存WIP日记账无法过账数据修复
  • Qt 自动根据编译的dll或exe 将相关dll文件复制到目标文件夹
  • 【Docker】Docker部署多种容器
  • ubuntu20下编译linux1.0 (part1)
  • 海云安开发者安全智能助手D10荣膺 “ AI标杆产品 ” 称号,首席科学家齐大伟博士入选2024年度 “ 十大杰出青年 ”
  • HarmonyOS NEXT开发进阶(七):页面跳转
  • 【网络云SRE运维开发】2025第2周-每日【2025/01/12】小测-【第12章 rip路由协议】理论和实操考试题解析
  • 504 Gateway Timeout:网关超时解决方法
  • 线程池底部工作原理
  • Matplotlib 图表显示比例控制笔记
  • iOS - block
  • 换了城市ip属地会变吗?为什么换了城市IP属地不变
  • Dubbo泛化调用
  • springMVC实现文件上传
  • Java中的反射机制:动态操作类的秘密武器
  • PHP 字符串
  • doris:手动分区
  • ChatGPT正在朝着全面个人助手迈出重要一步,推出了一个名为“Tasks”的新功能
  • 防火墙配置的关键要素
  • 使用Redis防止重复发送RabbitMQ消息
  • C/C++新春烟花
  • UE_C++ —— UE反射系统
  • Quinlan C4.5剪枝U(0,6)U(1,16)等置信上限如何计算?
  • A4.Springboot-LLama3.2服务自动化构建(一)——构建docker镜像配置