Linux之文件系统,软硬连接和动静态库

Linux之文件系统,软硬连接和动静态库

  • 一.文件系统
    • 1.1磁盘的存储结构
    • 1.2CHS和LBA
    • 1.3ext2文件系统
  • 二.软硬连接
    • 2.1软链接
    • 2.2硬链接
  • 三.静态库和动态库
    • 3.1静态库与动态库的概念
    • 3.2静态库的创建与使用
    • 3.3动态库的创建与使用
    • 3.4动态库的加载

一.文件系统

在上篇的学习中我们知道了文件分为被打开的文件和未被打开的文件,对于被打开的文件我们学习了在内存中创建strct file来进行管理以及利用文件描述符表来和进程进行关联,那么对于存储在磁盘中未被打开的文件我们又是要如何进行管理的呢?
在了解如何管理之前我们需要思考一下对于磁盘中的文件我们进行管理的主要目的是为什么?存储在磁盘中的文件我们又没有进行使用那么我们管理它的目的是不是就是当我们想要使用它时能够快速的定位到文件上。
对于如何快速定位到一个文件我们就想到了利用路径的办法,但是有没有什么新的方法呢?在学习这些知识的同时我们还需要了解磁盘是怎么进行存储的以及操作系统是如何管理磁盘的。

1.1磁盘的存储结构

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
那么在了解了磁盘的大致存储结构后我们想要在磁盘上进行寻址就可以分为三步

  1. 选择哪一个盘面———选择哪一个磁头
  2. 选择该面的哪一个磁道
  3. 选择该磁道的哪一个扇区

通过这三步我们就可以在磁盘上进行精准的寻址,而这三步总称为CHS寻址法
并且既然我们可以向某个扇区中写入数据那么也可以向任意一个或者任意多个的扇区进行连续写入,同时向随机一个扇区写入也是可以的。

1.2CHS和LBA

在了解了磁盘的物理存储结构后我们就需要站在操作系统的层面上去考虑如何管理磁盘中的存储空间了。对于磁盘中具有多面多个磁道多个扇区的存储形式,我们需要考虑一种方法可以让其对于我们用户来说更加直观以及方便,那么我们是否可以将磁盘的盘片想象成线性空间呢?
在这里插入图片描述
在这种想法下我们是以扇区为最小存储单元,但是一个扇区只能够存储512个字节这是否有点过于小了。我们的文件动则几十上百kb最大甚至达到mb,以字节为存储单元确实不太方便操作系统来进行管理但是这种管理方式是可取的,不同的管理方式是操作系统基于不同的选择所创建处理。不同与以扇区为存储单元,操作系统可以基于文件系统来以文件块作为存储单元来进行数据存放。

而一个文件块可以存储4kb即4096个字节,而这种存储方式就叫做LBA(Logical Block Address)。但是LBA也是基于CHS来开发出的一种新方法,它的内核也是让操作系统将对于存储设备的管理转换为对于数组的增删查改

1.3ext2文件系统

现在我们使用笔记本或者电脑时通常会将系统文件存储在C盘中而其他的文件则会根据类型来存储到D盘或者E盘中,但是如果我们研究过自己电脑的配置时我们会发现我们貌似只有一个硬盘那么为什么会有C盘D盘E盘之说呢?
准确来说不应该叫做C盘D盘和E盘,应该叫做C区D区和E区,他们都是从一个硬盘中划分出来的不同区域那么假如我们有500GB的存储空间我们要如何对其进行管理呢?
在这里插入图片描述
以这种思想我们就开发出来文件系统这一概念,今天则以讲述ext2为主。
在这里插入图片描述
我们来一个个的讲述每一个块组中所存储的内容

  1. Date block(数据块):存放文件内容,用文件块组成的一个大块用来存储文件的内容
  2. inode table(inode表):存放文件属性 如 文件大小,所有者,最近修改时间,使用的数据块等。
    每个文件都有自己的inode,而inode是一个结构体其中存储着文件的属性我们可以通过ls -i 来查看每个文件的inode编号。
    在这里插入图片描述
  3. inode bitmap(inode位图):每个bit表示一个inode是否空闲可用。
    这是使用了我们在C++中学习的位图的方法,不仅节省空间又可以直观的查看每个inode的情况。
  4. Block bitmap(块位图):记录着Data Block中哪个数据块已经被占用,哪个数据块没有被占用。
  5. Group Description(组描述符):描述块组属性信息
  6. Super Block(超级块):存放文件系统本身的结构信息。记录的信息主要有:bolck 和 inode的总量,未使用的block和inode的数量,一个block和inode的大小,最近一次挂载的时间,最近一次写入数据的时间,最近一次检验磁盘的时间等其他文件系统的相关信息。Super Block的信息被破坏,可以说整个文件系统结构就被破坏了。

在了解了这些新概念后我们会产生几个问题:

  • 如果文件内容过大导致一个块组中的数据块存储不下了会怎么样呢?
    在inode中会使用数组的下标和使用的文件块进行映射。对于文件内容过大的情况下,操作系统会将下标与文件块的映射分为一次映射,二次映射和三次映射甚至更多,对于一次映射的文件块其中存储的就是文件的内容,但是二次映射的文件块中存储的就是这个文件的其他文件块的地址,可以让操作系统通过这个文件块访问到其他的文件块。而三次映射就是在二次映射的基础上让第二次映射的文件块中依然存储其他文件块的地址从而实现访问。而利用这种机制我们同样可以将文件的数据存储到其他块组的数据块中从而实现跨组存储和访问。
    在这里插入图片描述
  • 既然inode在不同的分区中具有唯一性,那么如何区分不同inode属于哪个分区哪个组块呢?
    在Linux中对于不同分区的区别就是不同文件的路径前缀区别,通过路径前缀的不同来判断我们处于哪个分区下。我们可以使用df命令来查看我们当前的分区。
    在这里插入图片描述

而对于是哪个组块则和磁盘盘片线性看待一样,系统会在每个组块的开头和结尾各自定义一个变量来划分不同inode处于哪些组块。

  • 在了解了系统只看inode后我们对于删除文件是否有了新的看法?
    在知道了有inode位图和块位图来查看各自的使用情况后我们发现删除一个文件只需要修改这两个位图的内容即可,即将inode位图中删除文件所对应的inode的bit位置0而块位图也是同样的操作。

  • 你说inode和文件名之间是相互映射的,那么怎么证明呢?
    这就需要聊到我们的目录,通过ls -i的操作我们发现目录也是一个文件,那么目录中存储的是什么内容呢?
    答案就是目录中存储的就是它内部直接保存的文件的文件名和inode的映射关系!
    这也就解释了为什么我们想要在目录中新建和删除一个文件时我们需要这个目录的“w”权限,因为我们需要将目录中存储的对应文件和inode的映射关系进行新增和删除。而想要修改一个文件的内容就需要对应的“w”权限。

  • 在知道了系统只认inode后系统是如何查找一个文件的呢?
    在知道了目录中会存储inode和文件名的映射关系后我们发现怪不得无论是我们使用命令行查找文件还是我们使用进程调用函数来查找文件都需要带上路径,当我们使用命令行查找时系统会根据命令行中的路径来一层一层的根据目录中的文件名和inode的映射关系来查找到最终的文件,而使用进程时我们知道一个环境变量叫做工作目录所以只要知道了路径就可以顺利的查找到了文件。

  • 什么是挂载?
    在块组中不仅会存储我们自己的文件信息,而且还会存储很多文件管理的数据这些数据是先一步存储到块组中的。在我们现实生活中我们想要将电脑中的一个分区中自己的数据清空时我们就会进行格式化,格式化会将用户自己产生的数据全部清空但是系统自带的数据就不会清空。那么在Linux中格式化一个分区后我们想要再次使用这个分区就需要将这个分区挂载到某个目录下
    挂载的操作就需要使用mount命令
    在这里插入图片描述

二.软硬连接

2.1软链接

软链接:也称为符号链接,是Linux系统中的一种特殊类型的文件,它包含对另一个文件或目录的引用路径。
从概念中我们可以知道他是一个文件,并类似于Windows系统中的快捷方式。那么怎么证明呢?
在这里插入图片描述
创建一个软连接的格式为:ln -s 被链接的文件名 链接的文件名
在这里插入图片描述

2.2硬链接

硬链接:可以将其理解为一个指向原始文件 inode 的指针,系统不会为它分配独立的 inode 和文件数据。原始文件和硬链接文件实际上是同一个文件,只是名字不同。
从概念中我们得知硬链接不是一个独立的文件,它只是一个文件名和inode之间的映射关系而已。证明一下:
在这里插入图片描述
硬链接和原文件是同一个文件那么怎么才能算删除了一个文件呢?
即没有文件名和inode进行映射时也可以说是没有人使用的时候。
那么这种操作是如何实现的?
在inode中会有一个整型变量记录着有多少个文件名和inode编号有映射关系,每多一个映射关系就+1,少一个就-1。当变量为零时说明文件被删除了。大家是不是听这个方法很耳熟,这就是我们之前学习C++时学到过的引用计数

我们之前提到过目录也是文件那么我们是否可以对目录进行硬链接呢?
在这里插入图片描述
那么这是为什么呢?
没有为什么!这就是语法的限制!但是我们可以发现创建一个空目录时它的硬链接数居然是2!这是因为目录中会有两个隐藏文件!而在学习了硬链接后我们再看这两个隐藏文件我们会有更深的理解了。
在这里插入图片描述

三.静态库和动态库

关于动静态库我们在介绍gcc工具的时候讲到过,但是当时我们只了解了动静态库的概念,其内里的知识我们并没有提及到,今天我们就要学习如何在Linux中创建和使用动静态库。

3.1静态库与动态库的概念

  • 静态库是指编译链接时,把库文件的代码全部拷贝到可执行文件中,因此生成的文件比较大,但在运行时也就不再需要库文件了。其后缀名一般为“.a”
  • 动态库与之相反,在编译链接时并没有把库文件的代码加入到可执行文件中,而是在程序执行时由运行时链接文件加载库,这样可以节省系统的开销。动态库一般后缀名为“.so”,如前面所述的 libc.so.6 就是动态库。gcc 在编译时默认使用动态库。而在gcc后第一个选项加上-static则可以指定使用静态库进行编译。

3.2静态库的创建与使用

在这里插入图片描述
我们需要头文件来声明函数,但是我们不需要.c文件或者说我们不需要给人看的.c文件我们只需要将.c文件经过预处理,编译,汇编后形成的二进制文件即.o文件即可。
那么四个.c文件全部变为.o文件后呢?还是一个一个的使用吗?
不,我们可以将其打包到一起形成一个库文件,而这就是静态库
所以静态库的本质就是将库中的源代码经过汇编形成.o文件后再将其打包起来

那么如何创建一个静态库呢?
我们需要使用ar命令
其格式是:ar -rc lib静态库名字.a .o文件
其中**-rc的意思是replace和create 而lib是静态库的前缀,.a是静态库的后缀。**
在这里插入图片描述

在学会如何创建一个静态库后我们就要学习如何使用静态库

  1. 假设作为一个用户我们当前将源代码都已经书写完成了,那么要如何才能利用静态库来生成可执行文件呢?
    在这里插入图片描述
  2. 我们现在已经有了源文件,那么大家可以想到我们还缺少头文件和静态库,所以我们可以将头文件和静态库移到当前目录中来
    在这里插入图片描述
  3. 正常在有了头文件和静态库后我们就可以使用编译器来生成可执行文件了
    在这里插入图片描述
  4. 奇怪了,为什么提示我们没有定义这四个函数呢?
    我可以告诉大家这是链接报错,但是我们明明在静态库中打包了.o文件啊为什么还会出错呢?

这里就需要告诉大家一个概念,由我们自己创建的静态库属于第三方库,编译器gcc默认是不认识第三方库的,所以我们在使用gcc生成可执行文件时我们需要给编译器提供我们需要的库的名称

在这里插入图片描述

  1. 但是为什么现在又提示无法找到静态库呢?我不是都指明静态库的名字了吗?

这是因为对于gcc来说它默认是在linux中/usr/lib64中查找库的,但是我们自己创建的库并不在lib目录下所以我们还需要给gcc一个库文件的搜索路径
在这里插入图片描述

在这里插入图片描述

  1. 但是这种做法是否过于粗糙了呢,就这么将头文件和静态库移动到目录中,那么我们是不是可以专门创建一个目录来存放头文件和静态库呢?这样对于用户来说只有一个源文件和一个目录即可。
    在这里插入图片描述

而我们通过ldd命令就可以查看可执行文件所依赖的库有哪些
在这里插入图片描述
我们不是使用了自己创建的静态库了吗?为什么显示出来的库文件中没有自己创建的库文件呢?
这是因为ldd只能查询到可执行文件所依赖的动态库,而且对于静态库来说当可执行文件开始执行的时候静态库的内容就已经全部拷贝到可执行文件中了当然是查不到的。
同时在我们使用gcc时我们要知道gcc默认是使用动态链接的,但是对于一些库文件如果你只提供了静态库那么只能局部的使用静态链接但是其他的库还是使用动态链接的,除非你在使用gcc时加上-static,这就要求编译器只能使用静态链接了。

3.3动态库的创建与使用

在学习了如何创建和使用静态库后对于动态库的创建我们就非常的得心应手了,直接上代码
在这里插入图片描述
那么对于动态库的使用除了有和静态库那样增加各种参数来查找头文件和动态库以外还有什么办法呢?

  1. 直接安装到系统中
    刚刚我们说到gcc编译器会先在系统的库文件中查询库那么我们将头文件和自己创建的库全部安装到gcc的默认查找路径下即可。
    在这里插入图片描述
    在这里插入图片描述

  2. 使用软连接,查找动态库
    在这里插入图片描述
    在这里插入图片描述

  3. 修改环境变量LD_LIBRARY_PATH
    在系统中存在一个环境变量LD_LIBRARY_PATH,里面记录了程序运行期间查找动态链接库时,指定除了系统默认路径(/usr/lib)之外的路径。所以我们可以通过修改其来让系统找到我们想要的动态库
    在这里插入图片描述

  4. 直接修改系统关于动态库的配置文件
    在系统中会在/etc/ld.so.conf.d配置文件目录下存储系统管理所有动态库加载的配置文件,而这些配置文件里只存储了一些路径,所以如果我们想要让系统永久都能找到我们的动态库我们只需要在这个目录下自己新增一个配置文件并且在文件中存储我们动态库的路径即可。
    在这里插入图片描述
    在这里插入图片描述

3.4动态库的加载

对于静态库来说是没有加载这个过程的,因为在可执行程序运行的时候静态库中的内容就已经全部拷贝到可执行文件中了而且每个链接了静态库的可执行文件都要存储静态库中的内容这也就是为什么静态库的缺点生成的文件过大

而对于动态库却有一套自己的加载过程,在了解加载过程的时候我们也会学习到一些新知识。

Linux下生成的可执行文件通常被叫做ELF格式的可执行文件,这些可执行文件的特点是在文件内部不仅会存储自身的内容和属性而且还会存储自己链接了哪些动态库的函数,所以也就导致了当可执行文件运行时文件要从磁盘中加载到内存的时候其链接的动态库也需要加载到内存中。
在这里插入图片描述
那么当程序没有被加载的时候在程序内部有地址吗?当变量名,函数名编译成二进制代码时还有对应的名字了吗?
当程序存储在磁盘中时即没有被加载的时候程序内部也是有地址的而且这些地址还是按照虚拟地址空间的方式来编址的,而变量名函数名等被编译成二进制代码时就不存在名字的概念了那时候存储的都是对应的地址了。
所以对于虚拟地址空间,它不仅是操作系统规定的同时在编译器进行编译的时候也遵守着这个规则,而这就是为了在加载的时候从磁盘文件到内存的时候更快的形成映射关系。

在之前学习虚拟地址空间时我们知道它规定了不同的范围来存储不同的变量信息,而对于虚拟地址空间来说遵守的编址规则通常是基地址加偏移量
在这里插入图片描述
而这种编址方法也被叫做绝对编址,当存储的函数变换了位置后我们就需要重新查找它的位置再进行访问。

有绝对编址就有相对编址,后者更多用于形成库中函数的地址。两者的差别就像有人问你和你朋友在哪你说你在北纬多少多少度,南纬多少多少度,而你朋友说你在学校大门口朝北走10米。相对编址更多也是以一种偏移量的方式阐述自己的地址。

说回动态库的加载过程,我们说到了动态库也需要被加载到内存中那么对于虚拟地址空间来说动态库是要被加载到哪里呢?
动态库会被加载到共享区中,或者说是被映射到了共享区中。
在这里插入图片描述

那么要如何使用相对编址才能让动态库可以在共享区的任意位置加载成功都可以被运行呢?这就和ELF可执行文件中存储的动态库函数的存储方法有关了!
在这里插入图片描述

并且动态库和静态库不同,无论有多少可执行文件链接了动态库在加载的时候我们只需要加载一份动态库即可。因为在可执行文件中都以及存储了偏移量所以所有的可执行文件只需要利用偏移量来使用动态库。这也就是为什么动态库又被叫做共享库同时也就是为什么动态库的优点节省空间

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

【项目开发】URL中井号(#)的技术细节

未经许可,不得转载。 文章目录 前言一、# 的基本含义二、# 不参与 HTTP 请求三、# 后的字符处理机制四、# 的变化不会触发网页重新加载五、# 的变化会记录在浏览器历史中六、通过 window.location.hash 操作七、onhashchange 事件八、Google 对 # 的处理机制前言 2023 年 9 月…

TikZ 绘图学习笔记

这篇笔记的所有代码如下: % !TEX TS-program pdflatex % !TEX encoding UTF-8 Unicode% This is a simple template for a LaTeX document using the "article" class. % See "book", "report", "letter" for other typ…

Android Framework层介绍

文章目录 前言一、Android Framework 层概述二、主要组件1. 应用程序接口(API)2. 系统服务3. Binder4. 资源管理5. Content Provider6. 广播接收器(BroadcastReceiver)7. 服务(Service) 三、与 Linux Kerne…

如何选择等保服务

在当今信息化高速发展的时代,企业信息系统已成为业务运营的核心支撑,其安全性直接关系到企业的生存与发展。为了应对日益复杂的网络安全威胁,国家推行了等级保护(简称等保)制度,作为一项基本的信息安全保障…

MCU中的定时器

第一章 定时器的应用场景 第二章 定时器的原理 2.1 定时器的计数原理 1. 定时器的本质是一个计数器; 2. 计数器是对输入的系统频率信号进行计数; 3. 每来一个周期的信号,计数器的cnt 加一。如果周期T表示为1s,来三个周期就表示…

主页任务与计算器任务

一、主页任务 /* Private includes -----------------------------------------------------------*/ //includes #include "user_TasksInit.h" #include "user_ScrRenewTask.h" #include "main.h" #include "rtc.h" #include "…

javascript 入门-01-变量声明

因缘际会 Alice: 编程入门好像很难吧,我能学会吗 ?我虽然是计算机专业的,但是我几乎没怎么写过代码。但是你先别说我菜,我身边的同学大家都是这样的 🤷 Bob: 那你能写冒泡排序或者求数组最大值吗 ? Alice: 冒泡排序写不出来,求数组最大值还能试试看。不过为什么问这个…

富士施乐DocuContre S2520报打开盖子A,取出纸张。代码077-900故障检修

故障描述: 一台富士施乐DocuContre S2520复印机开机报错:打开盖子A,取出纸张。代码077-900故障,用户之前经常卡纸,卡着、卡着就一直提示打开盖子A,取出纸张了;复印机屏幕提示如下图: 故障检修: 富士施乐DocuContre S2520复印机报打开盖子A,取出纸张。077-900的错误代…

MySQL事务相关面试题

MySQL事务 事务的特性是什么? 事务是一组操作的集合,是不可分割的单位,把所有操作作为一个整体要么同时成功,要么同时失败 ACID 并发事务问题 脏读:一个事务读到了另外一个事务还没有提交的数据 不可重复读&#x…

深度学习与飞桨 PaddlePaddle Fluid

编辑推荐 飞桨PaddlePaddle是百度推出的深度学习框架,不仅支撑了百度公司的很多业务和应用,而且随着其开源过程的推进,在其他行业得到普及和应用。 本书基于2019年7月4日发布的飞桨PaddlePaddle Fluid 1.5版本(后续版本会兼容旧版…

C++ | Leetcode C++题解之第564题寻找最近的回文数

题目&#xff1a; 题解&#xff1a; using ULL unsigned long long;class Solution { public:vector<ULL> getCandidates(const string& n) {int len n.length();vector<ULL> candidates {(ULL)pow(10, len - 1) - 1,(ULL)pow(10, len) 1,};ULL selfPrefi…

解决IDEA报包不存在,但实际存在的问题

前言 最近在把一个亿老项目交割给同事&#xff0c;同事在导入项目运行时遇到IDEA报包不存在&#xff0c;但实际存在的问题&#xff0c;最终通过以下方式解决 现象 在IDEA里启动运行项目&#xff0c;报某个类有问题&#xff0c;引入的包不存在。 点击这个引入的包&#xff0c;可…

Jenkins下载安装、构建部署到linux远程启动运行

Jenkins详细教程 Winodws下载安装Jenkins一、Jenkins配置Plugins插件管理1、汉化插件2、Maven插件3、重启Jenkins&#xff1a;Restart Safely插件4、文件传输&#xff1a;Publish Over SSH5、gitee插件6、清理插件&#xff1a;workspace cleanup system系统配置1、Gitee配置2、…

三、计算机视觉_04AlexNet、VggNet、ResNet设计思想

1、AlexNet 1.1 基本介绍 AlexNet是由Alex Krizhevsky、Ilya Sutskever和Geoffrey Hinton在2012年ImageNet大规模视觉识别挑战赛&#xff08;ILSVRC&#xff09;中提出的&#xff0c;它不仅赢得了当届的比赛&#xff0c;还激发了后续许多创新的神经网络架构&#xff08;如VGGN…

基于SpringBoot的在线考试系统的设计与实现+文档

&#x1f497;博主介绍&#x1f497;&#xff1a;✌在职Java研发工程师、专注于程序设计、源码分享、技术交流、专注于Java技术领域和毕业设计✌ 温馨提示&#xff1a;文末有 CSDN 平台官方提供的老师 Wechat / QQ 名片 :) Java精品实战案例《700套》 2025最新毕业设计选题推荐…

LabVIEW三针自动校准系统

基于LabVIEW的智能三针自动校准系统采用非接触式激光测径仪对标准三针进行精确测量。系统通过LabVIEW软件平台与硬件设备的协同工作&#xff0c;实现了数据自动采集、处理及报告生成&#xff0c;大幅提高了校准精度与效率&#xff0c;并有效降低了人为操作误差。 一、项目背景…

群控系统服务端开发模式-应用开发-前端上传配置功能开发

一、添加视图 在根目录下src文件夹下views文件夹下param文件夹下system文件夹下&#xff0c;新建index.vue&#xff0c;代码如下 <template><el-tabs type"border-card"><el-tab-pane v-if"$store.getters.butts.includes(ParamSystemIndexDeta…

VAM本体整合包,本体人物卡

已更至2024年11月】全网人物卡最全&#xff01;所见即所得解压既玩。资源整合包较大&#xff0c;选择性下载想玩什么下什么&#xff01;&#xff01;&#xff01; 1.包含上千付费级精品场景&#xff0c;新增数位神佬合集&#xff0c;新增绝版素材。 2.没有场景是没有灵魂的&…

jmeter常用配置元件介绍总结之监听器

系列文章目录 1.windows、linux安装jmeter及设置中文显示 2.jmeter常用配置元件介绍总结之安装插件 3.jmeter常用配置元件介绍总结之线程组 4.jmeter常用配置元件介绍总结之函数助手 5.jmeter常用配置元件介绍总结之取样器 6.jmeter常用配置元件介绍总结之jsr223执行pytho…

蓝绿色电影风格滑板运动自拍照Lr调色教程,手机滤镜PS+Lightroom预设下载!

调色教程 蓝绿色电影风格的滑板运动自拍照&#xff0c;通过 Lightroom 调色&#xff0c;将滑板运动的活力与电影般的质感相结合。这种风格以独特的蓝绿色调为主&#xff0c;营造出一种神秘、宁静又充满活力的氛围&#xff0c;仿佛将瞬间定格成电影画面中的一帧。 预设信息 调…