打开文件 和 文件系统的文件产生关联

补充1:硬件级别磁盘和内存之间数据交互的基本单位
OS的内存管理
内存的本质是对数据临时存/取,把内存看成很大的缓冲区

物理内存和磁盘交互的单位是4KB,磁盘中未被打开的文件数据块也是4KB,所以磁盘中页帧也是4KB,内存中叫页框
在这里插入图片描述

我这个文件可能没有4KB,就一个字节,但不好意思加载4KB
我这个文件4KB,想修改1字节,也得加载4KB

为什么它不是要多少加载多少,而是一个固定大小4KB呢?
1、和磁盘交互比较慢,一共4KB每次要1KB的效率不如一气直接4KB,因为磁盘只需要定位一次
2、如果4KB文件你只要100字节,你能保证你下一次不用这文件上下文的其他数据吗?反正拿100字节还是4KB效率差不多,因为估摸着你后面的字节大概率也要用
局部性原理:正在访问代码区域附近也大概率会有数据代码被访问
这是一种预加载机制

那系统中向文件写了100字节,实际上保存100字节需要4KB?把数据交换的物理内存也要花4KB?
是的,文件大小从中做了一些事情
不用担心浪费问题,文件特别大前面那些内容把4KB都写满了,只有最后一个块被浪费了,小文件的就更不用说了

补充2:操作系统如何管理内存
在这里插入图片描述

操作系统必须能看到内存的物理地址
操作系统如何管理内存呢?
内存已经是一个一个4KB大小,非常多
我怎么知道哪些4KB被用到了,那些没被用
先描述,在组织!
struct page
{
//page页必要的属性信息
}
描述其中一个4KB
物理内存4G B 就有100多万的页
在这里插入图片描述
struct page mem_array[1048576];
对内存的管理变成了对数组的管理!!
数组天然是有下标的,所以每一个page天然有了页号的概念
如果此时任意一个地址0x11223344 & 0xFFFF F000,相当于求的是这个页的4KB对齐的起始地址
有了这个任意页的地址,应该就能通过找到对应的page数组对应的下标(我猜就是页地址也就是&完的地址减去第一个Page地址然后除以4就能得到下标)(都拿到地址了还有啥找不到的),进行物理内存管理
结论:
所有申请内存的动作,都是在访问内存page数组,都是对这个数组增删查改
在这里插入图片描述
在这里插入图片描述

struct page mem_array[1048576] 一定像链表一样有对应的数据结构方法,调算法申请内存

补充3:Linux中,我们的每一个进程、打开的每一个文件都要有自己的inode属性和自己的文件页缓冲区(内核缓冲区)

在开机时,把文件系统中的管理属性已经预加载到内存中了,尤其是super block GDT等文件系统方面的信息
比如这个分区上面就是操作系统文件,都要读,所以OS提前预加载到内存中
每个分区可能用的不同文件系统,OS中存在把所有的super block用双链表链接起来,OS知道每个分区大概在哪,每个分区文件系统什么样
在这里插入图片描述
关于打开一个文件时,OS要做什么工作,理解内核文件级缓冲区概念

打开一个文件时,struct file只保存了少数的文件属性,OS要为struct file构建一个数据结构struct inode才会保存文件的大部分属性,当打开文件时,根据对应目录中的数据块文件名映射找到inode编号,在已经预加载到物理内存中 的inode bitmap确认文件存在,然后在inode table 把对应的inode属性填入struct inode里

struct file 通过指针要能找到对应的struct inode,文件属性也就有了
在这里插入图片描述
内核中的struct file 与struct inode指针
在这里插入图片描述

文件属性其实不难找,文件内容呢?
C语言提供缓冲区,通过fprintf把数据写到缓冲区,通过fd我这个进程找到对应文件struct file
最终又怎么把数据写到对应磁盘上呢?
struct file中存在 address_space结构指针,这个结构包含一颗树page_tree,可以想象成一颗多叉树,树的节点中保存了指针数组,在叶子节点中保存了一个一个的struct page对象,而一个struct page对应物理内存4KB大小页框,所以应用层数据按照顺序从用户级缓冲区-> fd -> struct file -> address_space -> page_tree->叶子结点中的struct page然后再往物理内存中4KB中写入,就写到物理内存中了
我们看待物理内存时,只要找到对应的page,就能把数据写到物理内存里了
在这里插入图片描述
这颗树就叫文件的页缓冲区,此时我们把数据从应用层写到了由page管理的一个个内存中

补充4:
你说这玩意是个树,那是个什么树呢?
在这里插入图片描述
基数树 or 基树 本质是 字典树
数组有3个,那么这颗树就干上3层
void* slot[3]数组下标是数字,当我把他当成字母
每个数组又指向一个节点,就形成了这么一棵树
如果key是bca ,那么按照key的顺序就从根节点从上往下找
各种三个字母的组合就能根据这颗树找到某个底层叶子对象了
在这里插入图片描述

文件的内容是有偏移量的
假设文件大小10MB,也就是10x1024x1024字节
按照[0,1010241024]字节范围空间来看待
按照4KB来划分成一个一个的块
一共有多少个块呢?
1010241024/4*1024 = 2560个块
也就是说整个文件在磁盘上占2560个数据块
磁盘中每个块也就有了编号,从【1,2560】
每个数字乘以4096就是编号对应4KB在原始文件中的偏移量
所以把【1,2560】的编号按照Int来看待,有32bit位
假设0xFF FF FF FF 每八个bit看做一个字母Key = b,c ,a…
在这里插入图片描述

如果我们构建出这样的字典树,我们就可以拿着文件内容把文件内容的偏移量按照比特位分成特定的几个区域,八个bit为看成第一个字母b,后面依次类推,然后对应的字典树中就能找到整个文件中的偏移量和内存中page的映射关系
在这里插入图片描述
拿着文件的内容偏移量和内存的page建立映射关系,当我进行读写文件时,从开头读,结尾读,读写哪里,每一个读写都有偏移量,有偏移量找这颗树中偏移量对应的内存中某一个page,这样就能把数据保存到page里

其实最终想说的是文件写入把用户缓冲区的数据通过内核数据结构找到对应的Page对象把数据刷新到物理内存中了
接下来的工作就是OS要定期把数据刷到文件系统data blocks里面
在这里插入图片描述
此时数据已经写在物理内存中了,树里面的struct page就可以对应到物理内存中的page了
写完进程还管不管心数据刷到磁盘这个过程呢?
他就不关心了
所以这个数据刷新不刷新完全由OS决定,从这开始就往驱动层面走了
在这里插入图片描述

总结:
1、一个磁盘对应的文件它在访问之前部分对应文件系统中的属性已经加载内存了
2、进程打开文件时,本质就是把磁盘中的属性往struct inode 放
内容blocks通过struct file也能找到,以page的形式保存好
3、用户层写入时,通过fd-》 struct file-》 address-》 找到管理基树 找到物理内存中对应的page
然后把数据刷新到对应page页里,最后由OS调用IO子系统,把数据通过IO队列刷新到硬件上

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/194369.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

简单理解路由重分发(用两路由器来理解)

相关命令: default-information originate //*重分发默认路由 redistribute rip subnets //*重分发rip redistribute ospf 1 metric 3 //*重分发ospf(其中:1是ospf进程id 3是跳数) redistribute sta…

电池故障估计:Realistic fault detection of li-ion battery via dynamical deep learning

昇科能源、清华大学欧阳明高院士团队等的最新研究成果《动态深度学习实现锂离子电池异常检测》,用已经处理的整车充电段数据,分析车辆当前或近期是否存在故障。 思想步骤: 用正常电池的充电片段数据构造训练集,用如下的方式构造…

吴恩达《机器学习》8-5->8-6:特征与直观理解I、样本与值观理解II

8.5、特征与直观理解I 一、神经网络的学习特性 神经网络通过学习可以得出自身的一系列特征。相对于普通的逻辑回归,在使用原始特征 x1​,x2​,...,xn​ 时受到一定的限制。虽然可以使用一些二项式项来组合这些特征,但仍然受到原始特征的限制。在神经网…

Unity中Shader图形流水线中的纹理

文章目录 前言一、图形流水线中的纹理1、我们的纹理一般用于:2、纹理的获取方式: 二、纹理的分类1、颜色纹理2、几何纹理 三、纹理管线四、纹理的作用1、纹理可以 替换 漫反射模型中的 漫反射系数Kd2、纹理还有的作用 前言 Unity中Shader图形流水线中的…

为什么LDO一般不用在大电流场景?

首先了解一下LDO是什么? LDO(low dropout regulator,低压差线性稳压器)或者低压降稳压器,它的典型特性就是压降。 那么什么是压降? 压降电压 VDO 是指为实现正常稳压,输入电压 VIN 必须高出 所…

Qt QWebSocket实现JS调用C++

目录 前言1、QWebChannel如何与网页通信2、QWebSocketQWebChannel与网页通信2.1 WebSocketTransport2.2 WebSocketClientWrapper2.3 初始化WebSocket服务器2.4 前端网页代码修改 总结 前言 本篇主要介绍实现JS调用C的另一种方式,即QWebSocketQWebChannel。与之前的…

云服务器windows service2022 部署git服务器

1 安装 下载地址gitblit 解压到你的一个目录,我这里给的是C:\gitblit 根据官网提示要下载jre or jdk7.0,这里建议使用下载jre (jdk 有时候运行出问题,或者2个都安装),自行安装java,这里不做环境配置的说明 ==================================== 进入c:\gitblit\data 目录里面…

Docker - 企业项目

Docker - 企业项目 因为环境原因,本章本人没有实际操作,以理论为主 容器单独没有什么意义,有意义的是容器的编排 Docker 4台:1核2G的ECS K8s 9台:2核4G的ECS Docker Compose Docker Swarm # manager节点初始化sw…

场景图形管理-多视图多窗口渲染示例(4)

多视图多窗口渲染示例的代码如程序清单8-6所示 // 多视图多窗口渲染示例 void compositeViewer_8_6(const string &strDataFolder) {// 创建一个CompositeViewer对象osg::ref_ptr<osgViewer::CompositeViewer> viewer new osgViewer::CompositeViewer();// 创建两个…

时间序列预测实战(十五)PyTorch实现GRU模型长期预测并可视化结果

往期回顾&#xff1a;时间序列预测专栏——包含上百种时间序列模型带你从入门到精通时间序列预测 一、本文介绍 本文讲解的实战内容是GRU(门控循环单元)&#xff0c;本文的实战内容通过时间序列领域最经典的数据集——电力负荷数据集为例&#xff0c;深入的了解GRU的基本原理和…

Spring Framework 简介与起源

Spring是用于企业Java应用程序开发的最流行的应用程序开发框架。全球数百万开发人员使用Spring Framework创建高性能、易于测试和可重用的代码。 Spring Framework是一个开源的Java平台。它最初由Rod Johnson编写&#xff0c;并于2003年6月在Apache 2.0许可下首次发布。 Spri…

使用 Java 枚举和自定义数据类型

介绍 在 Java 编程领域&#xff0c;理解并有效利用枚举和自定义数据类型对于编写健壮、可维护且高效的代码至关重要。这篇文章旨在深入研究 Java 枚举和自定义数据类型的概念&#xff0c;提供见解和示例&#xff0c;以增强您的编码技能和知识。 理解 Java 中的枚举 枚举是枚…

C语言对10个数进行排序,使用快速排序算法

完整代码&#xff1a; // 对10个数进行排序&#xff0c;使用快速排序算法 #include<stdio.h>//用第一个元素将待排序序列划分成左右两个部分&#xff0c;返回排序后low的位置&#xff0c;即枢轴的位置 int partition(int arr[],int low,int high){//让待排序序列中的第一…

Android修行手册-Gson中不用实体类生成JsonObject或JsonArray

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例点击跳转>软考全系列点击跳转>蓝桥系列点击跳转>ChatGPT和AIGC &#x1f449;关于作者 专…

9.程序的机器级代码表示,CISC和RISC

目录 一. x86汇遍语言基础&#xff08;Intel格式&#xff09; 二. AT&T格式汇编语言 三. 程序的机器级代码表示 &#xff08;1&#xff09;选择语句 &#xff08;2&#xff09;循环语句 &#xff08;3&#xff09;函数调用 1.函数调用命令 2.栈帧及其访问 3.栈帧的…

狂神说笔记 快速入门Nginx

公司产品出现瓶颈&#xff1f; 我们公司项目刚刚上线的时候&#xff0c;并发量小&#xff0c;用户使用的少&#xff0c;所以在低并发的情况下&#xff0c;一个jar包启动应用就够了&#xff0c;然后内部tomcat返回内容给用户。 但是慢慢的&#xff0c;使用我们平台的用户越来…

逻辑回归-癌症病预测与不均衡样本评估

1.注册相关库(在命令行输入&#xff09; pip install scikit-learn pip install pandas pip install numpy 2.导入相关库 import pandas as pd import numpy as np from sklearn.metrics import classification_report from sklearn.model_selection import train_test_split…

黑马点评回顾 redis实现共享session

文章目录 传统session缺点整体访问流程代码实现生成验证码登录 问题具体思路 传统session缺点 传统单体项目一般是把session存入tomcat&#xff0c;但是每个tomcat中都有一份属于自己的session,假设用户第一次访问第一台tomcat&#xff0c;并且把自己的信息存放到第一台服务器…

场景图形管理-多视图与相机(3)

在OSG中多视图的管理是通过osgViewer::CompositeViewer类来实现的。该类负责多个视图的管理及同步工作&#xff0c;继承自osgViewer;:ViewerBase类&#xff0c;继承关系图如图8-13所示 图8-13 osgViewer::CompositeViewer 的继承关系图 在前面已经讲到&#xff0c;osgViewer:Vi…

ubuntu中使用 vscode 连接docker开发环境

文章目录 ubuntu中使用 vscode 连接docker开发环境步骤一&#xff1a;安装 Remote Development 插件步骤二&#xff1a;连接远程环境步骤三&#xff1a;开发 问题解决参考连接 ubuntu中使用 vscode 连接docker开发环境 Remote Development 是一个 Visual Studio Code 插件&…