如何理解 Linux 当中 “一切皆文件“

我们在 操作系统 当中的所有操作,包括对文件的所有操作,最终其实都是 通过 进程来实现的。

我们想象我们实现的各种C/C++ 程序,或者是各种语言实现的程序,本质上都是要 编译形成 可执行文件,然后操作系统把这个可执行文件 变成进程,在我们看来就是这个程序跑起来了。

而基本的文件上的操作,基本上都依赖于进程来操作,想想我们在 windows 当中要修改一个文件,也是使用 记事本 ,word 等等的软件来修改的。

进程也是我们和操作系统之间,打交道 最为频繁使用的一种方式。

 而对于 显示器,键盘,网卡,磁盘等等这些外设,就算这些外设 在物理实现上是有很大差别的。但是,他们在方法的种类上是大同小异的。 磁盘 ,键盘 ,显示器都是有读写 操作的,只不过 磁盘有读有写,显示器只有写,键盘只有读,网卡也有读写。

操作系统为了能更好的管理这些个 外设,和 软件,都会为这些 设备 创建一个 描述方法,就是使用 struct 结构体来把这些设备的各种属性 保存起来,方便管理,管理的方式也简单,就是利用某种数据结构,把这些个 设备的 结构体对象按照某种算法链接起来,这过程叫组织。也就有了 -- 先描述在组织的方式 。

这些外设,一定是有自己的 读写方法的。磁盘 有自己的 读写方法;显示器有自己的写方法,向显示器当中写数据;······

所以,在冯诺依曼体系结构当中的外设,都是有自己的 读写方法的。这也是我们想说的 IO设备。


所以,在操作系统看来,这些个 外设设备,其实都是 文件。我们要想访问一个 外设,在操作系统看来,其实我们就是想访问一个文件;所以访问文件的操作其实都是 通过 进程的方式去访问的。

将来,用户使用进程想打开某一个 外设之时,操作系统就是以 打开文件的方式给我们打开这个外设的,也就是使用 open()之类的函数来打开这个文件。

操作系统给每一个打开的文件,都创建一个数据结构 -- file_struct

那么,这些文件被用户进行读写操作,实际上就是要调用这个 设备的 读写方法(函数),Linux 如何 对上述情况进行解释呢?

其实,在 Linux 当中使用一个了数据结构 -- struct operation_func 。这个结构体。这个结构体的地址,一般在 文件对象当中就有保存,在这个结构体当中存储了 这个 设备的 各种对应 方法(函数)的 函数指针

以后,只要是 要打开一个文件,除了会创建这个 文件的 文件结构体对象之外,还会创建一个 方法集合(函数集合)的 结构体,在这个结构体当中存储的是 这个外设的各种对应 方法(函数)的 函数指针。

通过  struct operation_func 这个结构体当中的函数指针,找到 这些外设 的 各种方法,所以我们把这个 结构体称之为 方法集

 然后,进程通过 自己的 文件描述符表,当中保存的 文件对象首地址,找到各个 被打开的文件的文件对象。在这个文件对象当中就存储了一个 类似 *f_ops 的 指针,指向 这个文件的方法集 --  struct operation_func   结构体。

然后就能进行各种 对于外设的操作了。

所以,对于进程来说,也有read()和 write()之类的函数接口,在这个接口当中,通过指针的调用,来访问到 底层 外设的 方法:

 各个 文件对象当中的 各个方法,都有这样的类似的 调用接口,这样的话,实现不同指针调用方式,就可以调用不同的 外设硬件的 方法,从而操作这些 外设。

那么,在用户看来,就只调用了 这 一个 read ()函数,就完成了 对外设的访问,这不就和 在代码当中访问 文件的方式是一样的吗?


总结一下,什么叫一切皆文件?

其实就是 ,操作系统 帮我们在文件层面,封装了一层 类似 struct_file 这样的 文件结构体对象,文件当中有一个指针,指向另一个结构体,在这个结构体当中存储了 不同设备的 各种 方法,这个结构体就是 方法集。利用函数指针的方式,来间接的把 底层 外设硬件的各种方法 进行 汇总;

上层在使用这些方法之时,根本不关心底层 外设硬件的 各种方法是如何实现的,直接通过 文件对象 通过指针 来访问到这些 外设的方法即可。

所以,在进程层面,用户在调用之时,调用 read()这些函数,这些函数当中 有 各种设备的 各种方法的 函数指针指向,直接通过这个指针指向来调用即可。不关心中间的过程。

所以,在用户看来,Linux 一切皆文件。 

 我们把 文件对象这一层,也就是 struct_file 这一层,称之为 -- VFS。(虚拟文件系统


举个例子,如果 网卡这个设备 先要被打开的话,那么必须要给 操作系统提供自己的 驱动程序,也就是各种方法。然后操作系统为这个网卡创建 这个 网卡的 文件对象 -- struct_file。

同样,网卡也有自己的方法指针集。这些的结构体对象,按照 上述我们说过的方式连接起来,将来,某一个 进程 像打开网卡访问,只需要 调用 封装好的 方法,在这些方法当中其实就是 一些 指针的调用。

用户看来也是文件。

其实,从上层 文件对象 -> 方法集合 -> 外设的方法调用 -> 不同的外设。这个过程其实就类似 继承的关系,文件对象就是 基类,往后的 方法集合 , 各种外设 其实都可以看做是 这个 文件对象的 派生类。

在用户从 基类 (文件对象 或者是 进程)看来,都是在访问一个文件,但是访问不同文件,可以调用到 不同的 外设,调用到 不同的 外设方法,这不就是多态吗?


 我们来查看源码:

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux内存问题排查

目录 概念工具 概念 工具 vmstat:查看内存变化情况 通过vmstat,可以看到空闲列是否一直是减少的趋势,而缓冲和缓存一直不变,说明存在内存泄漏 top/htop ps pmap:查看进程的内存分布 bcc工具: memlea…

缩点+图论路径网络流:1114T4

http://cplusoj.com/d/senior/p/SS231114D 重新梳理一下题目 我们先建图 x → y x\to y x→y,然后对点分类:原串出现点,原串未出现点。 假如我们对一个原串出现点进行了操作,那么它剩余所有出边我们立刻去操作必然没有影响。所…

建造者模式(创建型)

目录 一、前言 二、建造者模式 三、链式编程实现建造者模式 四、总结 一、前言 当我们开发一个软件应用时,我们通常需要创建各种对象。有些对象是简单的,可以直接实例化,但有些对象则比较复杂,需要多个步骤才能创建完成。这时…

合肥中科深谷嵌入式项目实战——基于ARM语音识别的智能家居系统(二)

目录 基于ARM语音识别的智能家居系统 练习一 一、程序编译 练习二: 二、文件IO 三、文件IO常用API接口函数 1、打开文件 open() 2、将数据内容写入文件 write() 3、关闭(保存)文件 四、…

教务必备:php+Mysql多条件都输对版万用查分系统

查分吧PHP多条件都输对版已有表万用查询系统 V1.8 极简单文件实现一至多条件都输对成绩录取分班等通用查询。 支持隐藏指定列、支持网址列显示为图片或链接、支持验证码开关。 适合学校或教育机构信息中心技术员使用,快速部署并用于已有数据表查询。 无后台管理…

实战Leetcode(五)

Practice makes perfect! 实战一: 思路:我们要用复制的节点来组成一个新的链表,而原链表的节点随机指向其中一个节点,我们首先给每一个节点都复制并且插入到原来节点的后面,然后用复制的节点指向我们原来节…

CTFSHOW 文件上传

web151 JS前端绕过 直接上传 png的图片马 然后抓包修改为php asystem("ls /var/www/html"); asystem("cat /var/www/html/flag.php"); web152 和151一样的方法也可以实现上传 asystem("ls /var/www/html"); asystem("cat /var/www/html…

D. Jumping on Walls bfs

Problem - 199D - Codeforces 题目大意:有一个两个垂直的平行墙壁组成的一个峡谷。一个人初始是在左边墙壁第一层。在每个墙壁上有些障碍点,用X表示,这些障碍点不能被到达。,他可以执行以下三个操作: 向当前墙壁往上…

Swift制作打包framework

新建framework项目 设置生成fat包,包括模拟器x86_64和arm64 Buliding Settings -> Architectures -> Build Active Architecture Only 设置为NO 设置打包环境,选择release edit Scheme -> run -> Build configuration 设置为 Release 设置…

微信小程序:tabbar、事件绑定、数据绑定、模块化、模板语法、尺寸单位

目录 1. tabbar 1.1 什么是tabbar 1.2 配置tabbar 2. 事件绑定 2.1 准备表单 2.2 事件绑定 2.3 冒泡事件及非冒泡事件 3. 数据绑定 3.1 官方文档 4. 关于模块化 5. 模板语法 6. 尺寸单位 1. tabbar 1.1 什么是tabbar 下图中标记出来的部分即为tabbar&#xff1a…

vue实现类似c#一样,鼠标指到方法或者变量上,能显示自己备注的信息

之前从c#转vue的时候,就问同事,为啥我给刚写的方法备注,在其他地方调用的时候看不到备注信息,同事说不知道怎么才能做到。今天无意间看前端知识的时候发现了还有如下的方法: 如下,在变量之前增加多一个星号…

matlab二维曲面散点图插值方法

在 MATLAB 中,你可以使用以下函数进行二维曲面散点插值: griddata: 该函数可以在散点数据上进行二维插值,生成平滑的曲面。它支持多种插值方法,包括三次样条插值、最近邻插值、线性插值和自然邻近法插值。 scatteredInterpolant:…

当酱香碰上科技,茅台渴望的未来不仅仅是“加钱”

作者 | 曾响铃 文 | 响铃说 又涨价了。2023年11月1日起,贵州茅台宣布旗下53%vol茅台酒(飞天、五星)的出厂价格平均将上调20%,这也是茅台自2018年1月以来,近六年后再次迎来调整。 不过略有不同的是,本轮零…

雷达测角原理、测角精度、测角分辨率以及3DFFT角度估计算法汇总

1.角度测量方法 依据:电磁波的直线传播和雷达天线的方向性。 分类:振幅法测角、相位法测角 1.1 相位法测角 相位法测角利用多个天线所接收回波信号之间的相位差进行测角。如下图所示; 图 1 设在θ方向有一远区目标,则到达接收点…

基于非对称纳什谈判的多微网电能共享运行优化策略(附带MATLAB程序)

基于非对称纳什谈判的多微网电能共享运行优化策略MATLAB程序 参考文献: 《基于非对称纳什谈判的多微网电能共享运行优化策略》——吴锦领 资源地址: 基于非对称纳什谈判的多微网电能共享运行优化策略MATLAB程序 MATLAB代码:基于非对称纳什…

微信小程序 生命周期方法 页面路由 开发示例 自定义全局数据 链接跳转

目录 1. 生命周期方法 2. 页面路由 3. 开发示例 3.1 自定义全局数据 3.2 链接跳转 1. 生命周期方法 打开app.js Page生命周期函数 下面的Page生命周期图与上面的Page生命周期函数进行对比便于理解: 视图线程和应用服务线程会同时运行,应用服务线程…

动手学深度学习——序列模型

序列模型 1. 统计工具1.1 自回归模型1.2 马尔可夫模型 2. 训练3. 预测4. 小结 序列模型是一类机器学习模型,用于处理具有时序关系的数据。这些模型被广泛应用于自然语言处理、音频处理、时间序列分析等领域。 以下是几种常见的序列模型: 隐马尔可夫模型…

YOLO改进系列之注意力机制(CloAttention模型介绍)

CloAttention来自清华大学的团队提出的一篇论文CloFormer,作者从频域编码的角度认为现有的轻量级视觉Transformer中,大多数方法都只关注设计稀疏注意力,来有效地处理低频全局信息,而使用相对简单的方法处理高频局部信息。很少有方…

【汽车电子】CAN总线分析仪使用介绍(PCAN/同星CAN卡)

本篇文章以CAN卡的使用为基本线索,介绍了在汽车电子领域涉及的一些CAN卡使用流程,搭配强大的上位机可以实现诸多功能。文章并没有局限于一种CAN卡,而是针对PCAN和同星的CAN卡分别以常用CAN报文收发以及诊断控制台实现这两种方向进行了CAN卡使…

Java学习之路 —— Day2(OOP)

文章目录 1. 方法2. OOP2.1 static2.2 单例模式2.3 继承2.4 多态 3. 常用API3.1 包3.2 String3.3 ArrayList 1. 方法 方法定义时要使用public static修饰,这是和C最不同的地方,因为java都是基于类执行的。 Java的参数传递机制是值传递,即传…