深入解析:inode、软硬链接与动静态库的奥秘

news2024/11/16 8:32:14

在这里插入图片描述

目录

  • 一.inode
    • 1.inode的介绍
    • 2.文件系统与inode
    • 3.“目录”再理解
  • 二.软硬链接
    • 1.硬链接
    • 2.软连接
  • 三.动静态库
    • 1.静态库
    • 2.动态库
    • 3.动态库的加载过程

一.inode

1.inode的介绍

在Linux操作系统中,‘inode(索引节点)是文件系统的核心组件之一,用于管理文件和目录的元数据。每个文件和目录在磁盘上都有一个对应的inode`,它不包含文件的实际数据内容,而是记录了关于文件的关键信息。

简单来说,在Linux系统中,一个文件,有一个inode。每一个inode都有自己的inode编号(inode的设置,是以分区为单位的,不能跨分区)
inode表示文件的所有属性文件名,并不属于inode内的属性!
inode的组成结构:在Linux文件系统中,‘inode`包含以下信息:

  • ·文件类型:标识文件是普通文件、目录、符号链接还是其他类型。

  • 权限信息:包括文件的读、写、执行权限,以及文件所有者和所属组的信息。

  • ·所有者和组:文件的用户ID (UID)和组ID(GID)。

  • ·文件大小:文件的大小,以字节为单位。

  • 时间戳:包括文件的创建时间
    (ctime)、最后访问时间(atime)和最后修改时间(mtime)。

  • ·数据块指针:指向文件数据在磁盘上的实际位置。

2.文件系统与inode

在这里插入图片描述
上图为磁盘文件系统图可以帮助我们理解inode在文件系统中的作用。我们假设一个磁盘有512GB的空间,然后我们可以对这512gb进行分区,可能是两百多GB,然后在每个区都有一个启动块(Boot Block)和数干个Block group。其中启动块(Boot Block)包含启动启动过程所需的所有关键数据和指令。而Block group块组又可以分成由多个模块组成的结构。

  • 超级块(Super Block):存放文件系统的基本信息。里面包含着整个分区的基本使用情况记录的信息主要有:bolck 和 inode的总量,未使用的block和inode的数量,一个block和inode的大小,最近一次挂载的时间,最近一次写入数据的时间,最近一次检验磁盘的时间等其他文件系统的相关信息。Super Block的信息被破坏,可以说整个文件系统结构就被破坏了
  • GDT:是一个存储段描述符的表,它在系统引导时被加载到CPU的内部寄存器中。每个描述符定义了一个内存段的起始地址、大小和访问权限等。
  • Block Bitmap:Block Bitmap中记录着Data Block中哪个数据块的使用情况,比特位的位置和块号映射起来,表示该快是否被使用。
  • inode Bitmap:比特位和inode映射起来,表示inode是否空闲可用。
  • inode Table:inode表,单个inode表示文件的所有属性。
  • Data Blocks:数据块存放数据(文件内容)的地方,常见的是4kb,文件系统的块大小。
    可见在Linux系统中文件的内容和属性是分开存放的。

3.“目录”再理解

根据上面我们谈到的内容,应该怎么理解Linux下的目录呢?首先一切皆文件,目录肯定是个文件,我们又知道文件 = 内容 + 属性。那目录中存放的是什么呢:
该目录下文件名和对应文件inode的映射关系
接着我们回想在先前讲文件权限时,就能有更深的理解了:

  • 目录中没有写(w)权限时,我们无法创建文件的原因是无法在目录这个文件中写入对应的kv结构(文件名 对应文件的inode的映射关系)
  • 目录中没有读(r)权限,无法查看到目录下的文件,找不到文件的inode
  • 目录中没有修改(x)权限,无法cd进入文件,无法修改目录到环境变量。
  • 目录下不能有同名文件,目录中的key值不能重复。

二.软硬链接

1.硬链接

硬链接本质就是在特定目录的数据块中新增文件名和指向的文件的inode编号的映射关系。
在这里插入图片描述上图演示了硬链接的链接方式和删除方式(除了使用unlink删除链接还可以直接删除文件),现在我们可以知道在文件权限右边的数字其实代表的是文件的硬链接数目,只有当文件的硬链接等于0时才会被删除。
我们使用ls -li指令可以看到文件的inode信息,我们观察到硬链接的文件和源文件是同一个inode,因为硬链接不是独立的文件相当于取别名所以没有独立的inode。
Linux系统不支持对目录建立硬链接
在这里插入图片描述
虽是这么规定的,但是在上图所示中为什么目录还有不止一个硬链接数呢?其实是隐藏的.(当前目录)和…(上级目录)导致的,依靠这一特性,我们可以在不cd目录进去就可以知道一个目录下有着多少个文件。(硬链接数-2

2.软连接

软连接是一个独立的文件所以有独立的inode。
在这里插入图片描述
软连接数据块存放的是源文件的路径,所以可以理解为文件的快捷方式

三.动静态库

1.静态库

静态库(.a):程序在编译链接的时候把库的代码链接到可执行文件中。程序运行的时候将不再需要静态库
下面演示静态库的使用:
在这里插入图片描述
在这里插入图片描述
首先我们穿件test.h和test.c文件,做一个简单的函数声明和定义,紧接着创建Makefile文件
在这里插入图片描述
所谓生成静态库就是将.c 文件编译成.o文件然后将多个.o文件打包成静态库供用户使用
在这里插入图片描述
接着我们再创建一个目录,并将静态库复制过去,模拟用户的使用
在这里插入图片描述
用户拿到库 = 库 + .h 后,接着要写主函数使用库的功能。
在这里插入图片描述
接着我们编译时报错了:gcc不认识找不到这个头文件
![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/0f23ef8d62794cce89580b6465cb9ebb.png![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/f6eef2b74b914ef499dabb5bf8990e88.png
这时候我们就要用指令让编译器找到头文件
在这里插入图片描述
我们可以看到现在虽然头文件可以编过去,但是函数add他还是不认识,这说明是在链接时发生了问题
我们再将静态库指定给过去即可,这里要注意一定要写清静态库的名字,不能只给到路径,还有libXXX.a(静态库的名字是去掉前缀和后缀的XXX)。
在这里插入图片描述
这样子就可以完成了静态库的链接。对于上面的方法如果觉得太过复杂还有一些方法能解决问题:

  1. 将自己写的第三方库拷贝到系统库中
  2. 对头文件建立软连接,把软连接放在系统默认的库下面

2.动态库

动态库(.so):程序在运行的时候才去链接动态库的代码,多个程序共享使用库的代码
关于动态库还有几点需要了解一下:指令ldd能查看链接情况,gcc链接程序默认是动态链接的,如果系统中只提供我们对应的静态库,gcc则只能对该库静态链接,动静态库都有时我们可以指定static来链接静态库如果系统需要链接多个库,则gcc可以链接多个库
动态库链接比静态库链接相比较慢
在这里插入图片描述

我们再创建mymath.c.h,mylog.c.h文件用来演示链接静态库。首先和静态库一样,先gcc汇编成.o文件接着打包即可:
在这里插入图片描述

这里需要加的一个fPIC与位置无关码,我们后续再讲解。
在这里插入图片描述
我们再把.o文件打包即可形成动态库。
接下来我们试着使用Makefile构建自动化的生成动态库:
在这里插入图片描述

在这里插入图片描述
这样子我们的动静态库就都生成好了
接着我们像上次一样将包装好的库复制到用户文件下,然后用户编写main函数使用动态库:
在这里插入图片描述
在这里插入图片描述
根据上图可以看到,当我们明明告诉了gcc.h文件库和动态库的位置后,依旧是无法执行可执行程序,原因是我们只是告诉了编译器,你还要告诉加载器–系统,你的动态库在哪里。因为动态库是共享库在进程运行时是要被加载到物理内存中的
解决这个问题有几种方法在这个就不一一演示了:

解决加载找不到动态库的方法
1.拷贝到系统默认的库路径 /lib64 /usr/lib64/
2.在系统默认的库路径 /lib64 /usr/lib64/下建立软连接
3.将自己的库所在的路径,添加到系统的环境变量LD LIBRARY PATH中
4. /etc/ld.so.conf.d 建立自己的动态库路径的配置文件,然后重新ldconfig即可

3.动态库的加载过程

经过上面的讲解过后我们知道动态库在系统中加载过后,会被所有进程共享,那这是怎么做到的呢?
在这里插入图片描述
上图产生的问题,从而衍生出了fPIC–与位置无关码,可以让代码通过偏移量(相对地址),即使在有多个动态库在共享区时,也能正确的找到。

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

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

相关文章

从零开学C++:模板初阶

引言:在C语言当中,如果我们想要实现一个能计算整数和浮点数的计算器时,我们都需要根据不同的返回类型和参数类型创建许多个形式极其相似的函数,非常的麻烦,而在C中,我们将会引入模版的知识概念,…

模型优化—输入特征归一化处理

一、normalization 归一化(规范化)是对输入数据进行处理,使其满足某种规范。 前提:线性变换,不会改变原始数据的数值顺序。 假设原值分布在第一象限的某区间,并且x轴间距较广(离散&#xff0…

QT动态添加布局以及删除布局

具体代码示例如下 : QHBoxLayout* hLayout new QHBoxLayout;hLayout->addWidget(new QLabel("444"));hLayout->addWidget(new QLineEdit("444"));hLayout->addWidget(new QPushButton("444"));layout->addLayout(hLayou…

Axure Web端元件库:从Quick UI到500+组件的飞跃

在快速变化的数字世界中,产品设计不仅仅是功能的堆砌,更是用户体验的精心雕琢。原型设计作为产品开发过程中的关键环节,其重要性不言而喻。Axure,作为业界领先的原型设计工具,凭借其强大的交互设计和丰富的功能&#x…

Masked Autoencoders for Point CloudSelf-supervised Learning

关于SSL中的MAE方法。 摘要 文章介绍了一种新的技术,叫做MAE,在帮助计算机自己学习理解语言和图片方面做得非常好。受到这个技术的启发,它用在了点云上。点云是一堆代表三维空间中某些点的数据,这种数据有时候会有点难处理&…

机器学习笔记-02-基础线性算法认识(问题-解答自查版)

前言 以下问题以Q&A形式记录,基本上都是笔者在初学一轮后,掌握不牢或者频繁忘记的点 Q&A的形式有助于学习过程中时刻关注自己的输入与输出关系,也适合做查漏补缺和复盘。 本文可以让读者用作自查,答案在后面&#xff0…

尚庭公寓开发(二)

任何二进制和子网掩码进行一个与运算 得到是子网ip的话就是属于子网ip的范围 任何数字和一做与运算都是他本身 和0做运算都是0 所以要得到子网ip的话他的前面必须是 192.168.200 最后是0-255之间的范围 0不能取 0是子网本身 255也不能用 因为他是广播地址 真正可以使用 的范…

[数据集][目标检测]躺坐站识别检测数据集VOC+YOLO格式9488张3类别

数据集格式:Pascal VOC格式YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数):9488 标注数量(xml文件个数):9488 标注数量(txt文件个数):9488 标注…

Python升级打怪—Django入门

目录 一、Django简介 二、安装Django 三、创建Dajngo项目 (一) 创建项目 (二) 项目结构介绍 (三) 运行项目 (四) 结果 一、Django简介 Django是一个高级Python web框架,鼓励快速开发和干净、实用的设计。由经验丰富的开发人员构建,它解决了web开…

机器学习 | 分类算法原理——感知机

Hi,大家好,我是半亩花海。接着上次的内积继续更新《白话机器学习的数学》这本书的学习笔记,在此分享感知机这一回归算法基础。本章的回归算法基础基于《基于图像大小进行分类》项目,欢迎大家交流学习! 目录 一、感知机…

阿里云-物联网平台-IoT设备MQTT通信

阿里云-物联网平台-IoT设备MQTT通信 登录阿里云物联网平台创建产品添加设备查看设备客户端登录 登录阿里云 阿里云 注册账号,实名认证这些按提示操作即可不在赘述。 物联网平台 选择产品》物联网》物联网平台 进入管理控制台界面 开通服务 选择开通公共实例测试环…

oracle中存储过程的写法

存储过程常规语法: 实际业务例子: CREATE OR REPLACE TRIGGER "TRI_B00_02_ONLY_GUID" BEFORE/AFTER INSERT OR UPDATE OR DELETE ON B00_02 FOR EACH ROW declare t_guid varchar2(300) : ; --GUID t_cnt int : 0; BEGIN t_guid : :NEW…

Oracle核心进程详解并kill验证

Oracle核心进程详解并kill验证 文章目录 Oracle核心进程详解并kill验证一、说明二、核心进程详解2.1.PMON-进程监控进程2.2.SMON-系统监控进程2.3.DBWn-数据库块写入进程2.4. LGWR-日志写入器进程2.5. CKPT-检查点进程 三、Kill验证3.1.kill ckpt进程3.2.kill pmon进程3.3.kill…

Spring MVC笔记

Java 版本: JDK17 Eclipse: eclipse-jee-2023-12-R-win32-x86_64.zip Tomcat 10 JDK17采用springframework 6 *必须考虑兼容性问题&#xff0c;所以JDK 和spring framework不要乱搭配 初步创建Maven Project 安装包 修改poem.xml <dependency><groupId>org.sprin…

Spark实时(五):InputSource数据源案例演示

文章目录 InputSource数据源案例演示 一、​​​​​​​File Source 1、读取text文件 2、读取csv文件 3、读取json文件 二、Socket Source 三、Rate Source InputSource数据源案例演示 在Spark2.0版本之后&#xff0c;DataFrame和Dataset可以表示静态有边界的数据&am…

客户服务知识库最佳实践 7 个步骤

介绍 每个公司的声誉都依赖于其客户。 如果全世界都向你敞开了大门&#xff0c;但你最终在与客户打交道方面做得很糟糕&#xff0c;那么消息就会传出去&#xff0c;无论你的捕鼠器有多好&#xff0c;你都会失去销售。 正如营销依赖于与潜在客户的关系一样&#xff0c;公司的…

【Linux】信号3——信号的捕捉

1.信号的捕捉 我们都说信号被收到了&#xff0c;可能不会立马处理 信号是什么时候被处理的呢&#xff1f; 前提是我们得知道自己收到了信号&#xff0c;进程就得在合适的时候去查自己的pending表和block表&#xff0c;这些属于内核数据结构&#xff0c;进程一定要处于内核态&a…

Easy es问题总结

官网教程&#xff1a;https://www.easy-es.cn/pages/ac41f0/#settings 一 测试项目 1 pom <dependencies><!-- 排除springboot中内置的es依赖,以防和easy-es中的依赖冲突--><dependency><groupId>org.springframework.boot</groupId><artifa…

Java语言程序设计基础篇_编程练习题*15.26 (改变透明度)

*15.26 (改变透明度) 重写编程练习题15.24&#xff0c;当球摆动的时候改变球的透明度 思路&#xff1a;很简单&#xff0c;改写编程练习题15.24&#xff0c;为小圆Circle添加一个FadeTransition&#xff0c;再把暂停和开始方法设置在鼠标事件中 代码示例&#xff1a;编程练习…

基于多种机器学习的豆瓣电影评分预测与多维度可视化【可加系统】

有需要本项目的代码或文档以及全部资源&#xff0c;或者部署调试可以私信博主 在本研究中&#xff0c;我们采用Python编程语言&#xff0c;利用爬虫技术实时获取豆瓣电影最新数据。通过分析豆瓣网站的结构&#xff0c;我们设计了一套有效的策略来爬取电影相关的JSON格式数据。…