【文件fd】深入理解和实现Linux底下一切皆文件 | 系统和语言文件操作二者关系_封装 | 系统调用为什么怎样封装成库函数

目录

1.系统调用的打开/读/写文件操作

2.如何理解Linux底下一切皆文件

2.1设备属性

2.2设备的操作方法 

3.如何实现Linus底下一切皆文件

4.源码查看

5.系统和语言文件操作二者关系 

5.1 flags选项和C语言的"w""a"方式 二者的关系

5.2 系统的文件描述符fd和语言的FILE类型 二者的关系

5.3 封装

5.3.1 为什么要封装

5.3.2 怎样封装

6.联系&拓展


1.系统调用的打开/读/写文件操作

  • man 2 read
  • man 2 write
  • 读read的本质:是将内核级缓存的内容 拷贝到 用户级缓存区。

  • 若内核级缓存没有内容呢❓

  1. 如果没有数据,把当前进程放到磁盘设备的等待队列里面。
  2. 磁盘开始加载数据到内核级缓存中。
  3. 加载完毕,把进程唤醒,放入运行队列。
  • 写/修改write的本质:是将用户级缓存区的内容 拷贝到 内核级缓存当中,由OS定时刷新到外设。

  • 若原来内核级缓存区有内容呢❓

  • 即便内核级缓存有内容,需要再写入和修改,OS都必须先把内容从磁盘读到内存缓存中

  • write、read函数本质是拷贝函数

综上所述:无论读写操作,都必须在合适的时候,让OS把文件的内容读到文件缓冲区。

所以,对文件的修改是内核级的修改,不是磁盘级别。无论是全部修改完,只修改一个字节,都必须先加载到内核级缓存,在内存中修改完,由OS定期刷新到外设。


  • man 2 open
  • open是在干什么❓数据什么时候被刷新到外设(不管,OS安排)❓

  1. 创建文件对象struct file

  2. 开辟文件缓冲区的空间,加载文件数据(延后)

  3. 查询进程所对应的文件描述符表

  4. 文件对象struct file的地址,填入对应的文件描述符表中(下标对应)

  5. 返回文件描述符表的下标☞文件描述符

此刻就完成了,文件的打开工作。所以在应用层/用户层 读写数据,就是把应用层的数据和内核级的数据的相互交换/拷贝。

2.如何理解Linux底下一切皆文件

  • 磁盘中的文件,被打开的文件,OS会在内核中创建对应的文件对象struct file,给每个文件对象分配的数组下标(文件描述符),是从3开始。3456.....
  • OS默认打开设备文件,设备文件的文件描述符是0/1/2,底层是硬件,和磁盘上的普通文件不是一回事。如何理解呢硬件是文件❓
  • 这些硬件被打开,也必须在内核中创建对应的struct file,才能被归类到文件描述符表中,理解硬件<->文件的问题❓本质是:Linux底下一切皆文件。
  • 什么叫一切皆文件呢❓硬件也是文件。但是很明显,键盘/显示器/鼠标等是设备,不是文件。
  • 站在Linux系统角度,把硬件当作文件。这是怎么做到的❓
  • 0:标准输入,键盘。
  • 1:标准输出,显示器。
  • 2:标准错误,显示器。
  • 冯诺依曼体系中,所有的设备,叫做外设,IO设备。
  • 设备=设备的属性+设备的操作方法(重点先放在操作方法上)
  • OS是硬件的管理者,所以OS对每一种设备做管理。(先描述在组织)
  • 每一种设备在OS内核中都要存在对应的PCB☞struct device

2.1设备属性

  • 设备文件struct file☞有文件的属性和指针☞指向设备的属性☞struct device
  • struct device中的设备属性/类别都是一样(设备名/设备厂家等等),只是属性值是不一样的。
  • struct file☞文件相关属性+设备文件相关属性struct device

 

2.2设备的操作方法 

  • 每种设备都有设备各自的操作方法
  • 注❗键盘没有写方法write。显示器没有读方法read。可以将设备没有的方法设置为NULL即可。
  • 不同的设备的操作方法一定是不一样的❗
  • 设备的操作方法,都是由驱动层来完成的。
  • 驱动层:工程师来完成的,键盘工程师/显示器工程师等。
  • 每种工程师要写出来访问外设的操作方法☞函数 void k_read() 
  • 设备文件对象struct file里面还会包含设备操作方法的函数指针void (*read)(......) 函数 void k_read() 

站在OS角度,每一个被打开的设备,都必须在OS内核中创建一个设备对应的设备文件对象struct file。(在打开这个设备的时候,就必须创建struct file)

  • 属性角度:struct file里面包含一些指针☞指向设备文件相关的属性以及文件相关属性。
  • 操作方法角度:struct file里面包含函数指针☞指向外设的操作方法(函数)
  • 用户就不需要再考虑硬件的底层的差异。因为全抽象成 设备文件struct file结构体对象中☞struct file包含设备操作方法的函数指针void (*read)(......) 
  • 虽然底层设备的操作方法(函数实现)一定都是不一样的。
  • 同样不同的设备的不同操作方法(函数实现)可以抽象成一样的 返回值和参数
  • 实际上抽象struct file里面的函数指针(读方法/写方法等等)
  • 打开设备文件的本质:是创建了struct file后,将其中的函数指针指向这个设备的底层操作方法的函数。

综上所述:访问一个外设,只要找到这个设备的文件,直接调用函数指针指向的函数(操作方法),既可以访问设备了。同时也获取了设备文件的属性和文件的相关属性。

  • 所以,struct file可以是键盘设备文件/显示设备文件等等,也有存在内核级缓存,写和读就是内核级缓存和键盘/显示器硬件交互。(图)

  • 所以,每一个被打开的文件除了拥有内核级缓存,还需要一张操作底层方法的指针表。根本不需要知道这个struct file文件代表什么。它底层都会指向各自的属性和操作方法的。(图)

3.如何实现Linus底下一切皆文件

  • Linux底下一切皆文件的技术被称为:多态
  • struct file可以找到不同设备的属性和操作方法。(用C语言来实现类)
  • 类=属性+方法
  • 用C语言实现类:C语言结构体是只能放属性不能放方法,但是可以放函数指针(相当于放方法☞指向函数)。所以属性+函数指针(指向方法)
  • C语言实现的多态技术❗(图)
  • 虚拟文件系统:在Linux/软件工程领域 的问题 都可以直接或间接添加软件层来解决。图

4.源码查看

【设备文件的操作方法函数指针】

【设备文件的操作方法函数】

5.系统和语言文件操作二者关系 

5.1 flags选项和C语言的"w""a"方式 二者的关系

  • 在C语言中,使用的fopen/fclose等接口是库函数。

  • 语言层面上学习文件时,对应的库函数接口,底层都是系统调用。只不过做了封装。

  • 所有的C语言上的文件操作函数,本质底层都是对系统调用的封装 (图)

5.2 系统的文件描述符fd和语言的FILE类型 二者的关系

  • 进程打开文件☞进程维护的表:文件描述符表☞下标(文件描述符)☞ struct file
  • 在OS内,系统在访问文件的时候,只认文件描述符fd❗
  • 如何理解C语言通过FILE*访问文件呢❓

  • C语言编程语言:没有文件描述符fd,在访问文件使用的都是文件指针FILE*
  • FlLE是一个C语言提供的结构体类型。(课件最后)

  • FILE在语言层面上是一个结构体。在系统层面上OS只认识文件描述符fd。

  • 所以,FILE结构里面内部一定封装了文件描述符fd。文件流必须封装了文件描述符fd

证明FILE结构里面内部一定封装了文件描述符fd

  • man 3 fwrite
  • 第一个参数:缓冲区/字符串

  • 第二个参数: 基本单位的大小

  • 第三个参数: 写几个基本单位

  • 第四个参数:往哪个文件流中写

  • 返回值:实际写了多少个基本单元。

  • stdin / stdout / stderr 和 0/1/2

综上所述:语言层面上学习文件时,对应的接口,底层都是系统调用。只不过做了封装

在类型上。系统底层访问文件只能用文件描述符,语言上就用结构体封装了文件描述符。图

 【stdin / stdout / stderr 和 0/1/2】

5.3 封装

5.3.1 为什么要封装

  • 写代码,推荐使用语言提供的文件操作,不推荐系统调用(除非非用不可)。
  • Linux/MAC/windows操作系统一定是不一样的,体现在方方面面,系统调用接口也都不一样。
  • 如果在Linux上使用Linux系统调用接口写的代码,不一样能在其他操作系统上编译通过使用。
  • 系统调用不具有跨平台性
  • C/C++编程语言是具有可移植性,跨平台性的。
  • C/C++编程语言写的代码,无论是在Linux下还是其他系统下面都可以编译通过使用。 
  • 为什么要封装❓
  • 所以语言都想要具有跨平台性,所有语言要对不同的平台的系统调用进行封装(图)

5.3.2 怎样封装

  • 语言为什么具体跨平台性❓语言怎么做到具体跨平台性❓图
  • 编程语言的源代码中的标准库☞库的设计者
  • 在条件编译上 设计☞不同系统的条件下各自编译一份☞使用哪套系统就下载哪套编译完成的库即可
  • 同一语言☞针对不同的平台☞具有不同的标准库☞根据不同平台系统的需求下载不同的库
  • 库的底层☞不同平台系统 实现 是不同的☞但是语言会把他们封装成相同的。
  • 编程语言的标准库在不同系统的底层实现上是不一样的,但是经过编程语言的封装所使用的库函数接口是一样的。所以使用哪个平台,就安装此平台的语言的标准库。所以编程语言是具有跨平台性的。

6.联系&拓展

  • 打开文件就是打开一个设备(显示器),其实是终端。
  • 一个进程在运行时,默认会打开三个输入输出流。
  • /proc目录下是当前正在进程的pid
  • /proc/pid 目录下pid的进程的所启用文件的文件描述符/可执行程序/当前工作路径等等
  • 文件描述符☞终端(键盘/显示器)
  • /dev/pts/4就是的终端文件。进程把/dev/pts/4设备文件打开写入,相当于往终端写入。
  • 每次登录云服务器,shell是第一个进程,它就把0/1/2打开了。后面每打开一个终端,就会把shell创建的/dev/pts文件再次打开,增加新的终端对应的设备文件。
  • 终端不是显示器,显示器只有一个。但是可以有很多终端。


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

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

相关文章

Linux之基础IO(下)

目录 缓冲区的概念 深入理解文件系统 创建文件的整个过程 软链接 硬链接 上一节课我们学习了基础IO中的文件的读写操作&#xff0c;以及文件描述符的概念和重定向的基本原理&#xff0c;本期我们继续进行基础IO的学习。 缓冲区的概念 在讲缓冲区之前&#xff0c;大家先看…

Java 集合框架:HashMap 的介绍、使用、原理与源码解析

大家好&#xff0c;我是栗筝i&#xff0c;这篇文章是我的 “栗筝i 的 Java 技术栈” 专栏的第 020 篇文章&#xff0c;在 “栗筝i 的 Java 技术栈” 这个专栏中我会持续为大家更新 Java 技术相关全套技术栈内容。专栏的主要目标是已经有一定 Java 开发经验&#xff0c;并希望进…

Redis (常用数据结构和命令)

目录 简介 概述 特点 数据结构 常用命令 通用命令 keys del exists expire 与 ttl String 命令 SET 和GET: MSET和MGET INCR和INCRBY和DECY SETNX SETEX Redis 命令 Key 的层级结构 key层级关系 &#xff1a; Hash命令 HSET和HGET HMSET和HMGET HGETALL H…

TypeScript核心

常用操作方式 1、类型推断 ts会根据变量存放的初始值来进行变量类型限定。 如上&#xff1a;开始str是字符串&#xff0c;则此变量以后就只能存字符串值。 开发中的意义&#xff1a;变量分配字符串值&#xff0c;后期可能会书写一些字符串功能、方法等相关的操作&#xff0c;如…

【算法/学习】前缀和差分

前缀和&&差分目录 1. 前缀和的概念及作用 &#x1f308;概念 &#x1f308;用途 &#x1f319;一维前缀和 &#x1f319;二维前缀和 2. 差分的概念及用途 &#x1f308;概念&#xff1a; &#x1f308;用途 &#x1f319;一维差分 &#x1f319;二维差分 1. …

JVM面试题之内存区域、类加载篇

文章目录 引言JVM是什么&#xff1f;1. JVM内存划分2. 对象如何在JVM中创建2.1 内存分配2.2 创建对象步骤 3. JVM类加载流程3.1 双亲委派 总结 引言 Java开发人员在面试中基本都会被问到关于JVM的问题。想要成为高级的开发人员&#xff0c;了解和学习Java运行的原理和JVM是必不…

数据结构——二叉树性质

性质1:在二叉树的第i层上至多有2^(i-1)个结点(i>1)。 这个性质很好记忆&#xff0c;观察一下图6-5-5。 第一层是根结点&#xff0c;只有一个&#xff0c;所以2^(1-1)2^01。 第二层有两个&#xff0c;2^(2-1)22。 第三层有四个&#xff0c;2^(3-1)2^24。 第四层有八个&am…

【年报文本分析】Python+Selium获取互动易平台投资者提问与上市公司回应文本数据

目录 序言excel文件准备全部代码 序言 互动易平台链接&#xff1a;https://irm.cninfo.com.cn/views/interactiveAnswer 需要提前下载好三个库&#xff0c;都可以用pip install轻松下载&#xff0c;稍微麻烦点儿的是需要去下载个对应版本的chromedriver.exe驱动&#xff0c;放…

路由表与IP数据报的转发

前言&#xff1a;本博客仅作记录学习使用&#xff0c;部分图片出自网络&#xff0c;如有侵犯您的权益&#xff0c;请联系删除 一、相关知识 1、路由类型 路由表中有3类路由&#xff1a;直连路由、静态路由、动态路由 直连路由&#xff1a;一般指去往路由器接口直接连接网络的…

mysql中You can’t specify target table for update in FROM clause错误

mysql中You can’t specify target table for update in FROM clause错误 You cannot update a table and select directly from the same table in a subquery. mysql官网中有这句话&#xff0c;我们不能在一个语句中先在子查询中从某张表查出一些值&#xff0c;再update这张表…

【ffmpeg命令入门】视频剪切,倍速与倒放

文章目录 前言1. 视频剪切2. 视频倍速公式说明例子 3. 视频倒放总结 前言 在视频编辑中&#xff0c;剪切、倍速和倒放是常见的操作&#xff0c;能够帮助我们调整视频的长度、播放速度以及播放顺序。掌握 FFmpeg 命令中的相关参数和用法将使视频处理变得更加高效。在这篇文章中…

pytest使用

主要技术内容 1.pytest设计 接口测试 框架设想 common—公共的东西封装 1.request请求 2.Session 3.断言 4.Log 5.全局变量 6.shell命令 ❖ config---配置文件及读取 ❖ Log— ❖ payload—请求参数—*.yaml及读取 ❖ testcases—conftest.py; testcase1.py…….可…

2024年【熔化焊接与热切割】考试题及熔化焊接与热切割考试总结

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 熔化焊接与热切割考试题是安全生产模拟考试一点通生成的&#xff0c;熔化焊接与热切割证模拟考试题库是根据熔化焊接与热切割最新版教材汇编出熔化焊接与热切割仿真模拟考试。2024年【熔化焊接与热切割】考试题及熔化…

vue-plugin-hiprint 打印 预览打印+静默打印

1.安装 npm install vue-plugin-hiprint npm i socket.io-client --save //为了静默打印 &#xff08;为此还需安装客户端&#xff09; 2…html页面 引入css <link rel"stylesheet" type"text/css" media"print" href"https://cdn.jsde…

创新大赛中财务预测的策略与技巧

创新大赛中财务预测的策略与技巧 前言财务预测的重要性财务预测的步骤财务预测的关键要素注意事项结语 前言 在当今快节奏、竞争激烈的商业环境中&#xff0c;创新不仅是推动企业成长的动力&#xff0c;更是衡量一个项目能否在市场中脱颖而出的关键。创新大赛作为展示这些创新成…

星耀巴黎,竞猜有礼!为运动健儿加油,让世界看见中国力量

即将高燃来袭首金荣耀&#xff0c;让我们拭目以待&#xff01; 当象征着“更快、更高、更强”的号角再次吹响&#xff0c;谁又能在这场全球瞩目的体育盛宴中&#xff0c;率先触碰那份至高无上的荣耀&#xff1f;“首金”不仅是一个国家或地区体育实力的象征&#xff0c;更是运…

1台solidworks图形工作站同时给5人一起使用

在日益发展的科技环境中&#xff0c;团队协作已成为各个行业不可或缺的一一部分。对于工程设计和图形处理领域而言&#xff0c;SolidWorks等强 大的三维建模和仿真软件成为了日常工作的重要工具。 随着团队规模的扩大和项目复杂性的增加&#xff0c;如何高效、稳定地为多人提供…

Java入门:05.Java中的数组002

通过上篇文章&#xff0c;相信大家对数组应该有了一个简单的了解&#xff0c;并对Java中的数据类型有了一个基本的认识&#xff0c;不仅如此我们还明白了怎样定义一个数组类型的变量&#xff0c;在这之后&#xff0c;让我们一起来更加深入的了解一下数组吧。 三、如何创建一个…

Axure软件新功能解析与应用技巧分享

Axure是一种用于创建原型和交互设计的软件工具&#xff0c;广泛应用于操作界面。&#xff08;UI&#xff09;和客户体验&#xff08;UX&#xff09;为了展示和测试应用程序、网站或其他数据产品的性能和操作界面&#xff0c;设计帮助产品经理、设计师和开发者制作具有交互性的原…

Ghost Buster Pro for Mac:系统优化的得力助手

Ghost Buster Pro for Mac是一款功能强大的系统优化工具&#xff0c;专为Mac用户设计&#xff0c;旨在提供全方位的系统清理、优化和维护服务。 这款软件拥有出色的垃圾清理能力&#xff0c;能够深度扫描并清除Mac上的无效目录、文件、系统日志、下载历史记录、缓存和临时文件…