【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() 调用返回,读取操作完成。
原文地址:https://blog.csdn.net/m0_64014551/article/details/145117755
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!