顺德网站建设itshunde,网站代理备案步骤,新渝网门户网,html制作学校网页#x1f941;作者#xff1a; 华丞臧. #x1f4d5;专栏#xff1a;【LINUX】 各位读者老爷如果觉得博主写的不错#xff0c;请诸位多多支持(点赞收藏关注)。如果有错误的地方#xff0c;欢迎在评论区指出。 文章目录 一、Linux文件系统1.1 磁盘1.2 inode1.3 软硬… 作者 华丞臧. 专栏【LINUX】 各位读者老爷如果觉得博主写的不错请诸位多多支持(点赞收藏关注)。如果有错误的地方欢迎在评论区指出。 文章目录 一、Linux文件系统1.1 磁盘1.2 inode1.3 软硬链接1.4 动静态库 一、Linux文件系统
1.1 磁盘 信息化时代就是信息产生价值的时代信息化是当今时代发展的大趋势代表着先进生产力。通常我们都会将信息存放在某些硬件上如硬盘、内存等当信息存放硬盘上时信息就变成了硬盘上的文件人们通过一些设备如电脑手机可以查看使用这些数据我们的工作和生活已经完全离不开视频、音乐、图片、文本、表格这样的数据文件。 磁盘上存放着大量的文件这些文件需要被管理组织起来操作系统中管理和存储文件信息的软件机构称为文件系统。最开始存放数据的硬件是磁盘随着时代发展像我们的笔记本电脑大多使用SSD硬盘但是磁盘还是主要的存储设备可以用存放大量的数据关键是便宜。下图是一张磁盘的结构图磁盘的核心就是这些盘面盘面能够记录二进制序列其原理就是通过电流产生感应磁场来改变某些特定位置的磁极从而将电信号持久化到磁盘上。 磁盘工作时是处于一种高速旋转的状态磁头依靠磁盘的高速旋转引起的空气动力效应悬浮在盘面上磁头在副轴马达的带动下可以在极短的时间内精确的切换到数据所在的磁道。 磁盘是一种高精度的设备在高速旋转的情况下磁面上的一粒灰尘都可能会导致磁盘损坏因此磁盘通常是在无尘的环境下密封。 每一个盘面都对应一个磁臂通过这些磁臂上的磁头来定位数据的位置依次确定磁道柱面、盘面、以及扇区这三个值称为CHS地址。 扇区是硬盘的最小操作单位但扇区对于操作系统来说还是太小了一般操作系统有自己的硬盘操作最小单位在linux下一般为4k。 为了方便管理数据我们可以将硬盘这样的物理块设备分割成多个逻辑块设备。或者我们也可以将多个物理块设备组合成一个容量更大的逻辑块设备。 操作系统需要管理磁盘将磁盘抽象为一个线性的结构类似于卷尺拉出来是线性的收进去是圆形的因此我们可以将磁盘想象成线性的结构数组对磁盘的管理就可以转换成对数组空间的管理了。 假设磁盘抽象的出的数组为sector disk[100000000]那么我们定位一个扇区只需要数组的下标即可这种下标称为LBA–逻辑块地址将LBA转换成CHS地址再将数据写入对应的磁盘上去。 磁盘上存储的基本单位是扇区512字节常规文件系统访问磁盘的基本单位是4KB即一次IO访问8个扇区。 这样做有两个好处一、提高IO的效率 二、让软件OS和硬件磁盘具有强相关性即解耦合。
1.2 inode
使用ll查看文件除了文件名还可以看到文件的其他属性如下图 每行包含7列
模式代表文件的类型以及权限硬链接数文件所有者所属组文件大小最后修改时间文件名
如果需要查看文件更详细的信息可以使用stat命令如下图 在上图中我们可以看到文件属性中有一个Inode字段在Linux系统中inode用于表示唯一的一个文件。 不管是在Windows平台还是在Linux系统中我们都可以通过绝对路径或相对路径找到一个唯一的文件前提是在同一目录下都不允许重名的文件出现。文件是存放在磁盘上的不管是普通文本文件还是文件夹Linux上通常称为目录都属于文件的一种目录也是文件在这种情况下操作系统如何在磁盘上查找到目标文件的呢 —— 给定一个一对一的映射关系。 Linux ext2文件系统下图为磁盘一个分区的文件系统图内核内存映像肯定有所不同磁盘是典型的块设备硬盘分区被划分为一个个的block。一个block的大小是由格式化的时候确定的并且不可以更改。例如mke2fs的-b选项可以设定block大小为1024、2048或4096字节。而下图中启动块Boot Block的大小是确定的。 启动块Boot Block里面包含操作系统的位置以及分区表开机信息。Block Group ext2文件系统会根据分区的大小划分为数个Block Group。而每个Block Group都有着相同的结构组成。超级块Super Block存放文件系统本身的结构信息。记录的信息主要有bolck 和 inode的总量未使用的block和inode的数量一个block和inode的大小最近一次挂载的时间最近一次写入数据的时间最近一次检验磁盘的时间等其他文件系统的相关信息。Super Block的信息被破坏可以说整个文件系统结构就被破坏了因此超级快通常会备份一定数量。GDT(Group Descriptor Table) 块组描述符描述块组属性信息记录inode数、起始inode编号、block使用量以及剩余量等等信息。块位图Block BitmapBlock Bitmap中记录着Data Block中哪个数据块已经被占用哪个数据块没有被占用。inode位图inode Bitmap每个bit表示一个inode是否空闲可用。i节点表inode table以128字节为单位存放文件属性 如 文件大小所有者最近修改时间等。数据区Data Blocks以4KB为单位存放文件内容。
在inode table中保存了文件对应的所有属性那么一个inode如何与属于自己的文件内容关联起来呢
struct inode
{// 文件所有属性...blocks[15];...
}
//在inode的结构体中包含一个blocks的数组这个数组保存了文件对应的block编号
//其中[0, 11]直接保存该文件的blocks编号
//[12, 15]指向一个datablock但是这个datablock不保存有效数据而保存该文件所对应的其它块编号还要注意的是文件名也是文件属性但是inode里面并不保存文件名Linux下底层实际都是通过inode编号来标识文件。那么操作系统是如何准确帮用户通过文件名找到对应的文件内容呢首先用户对文件进行操作时都是在一个目录下不管是创建还是删除。其次目录也是一个文件既然是文件就有属性和内容其属性与普通文件类似那么目录文件的内容是什么呢 文件名并沒有被保存在文件内容中操作系统又必须通过文件名帮用户查找文件内容所以文件inode和文件名必须具有映射关系并且记录下来在Linux系统中文件名和文件inode的映射关系被保存在目录的内容中。同时我们也注意到Linux同一个目录下不可以创建多个同名文件这说明文件名本身是一个具有Key值的东西。 创建一个新文件当我们创建好一个新文件时操作系统会找到自己所处的目录下根据目录的inode编号查找到目录的datablock然后将文件名和inode映射关系写入目录的数据块中。删除文件操作系统删除一个文件并不会直接清除数据而是将标记该文件对应的属性和数据块的相关位图清除由1置0所以删除的文件是可以恢复的。
1.3 软硬链接
硬链接通过索引节点inode来链接。软链接通过名字引用另外一个文件。通过ls -l可以查看文件的硬链接数
//创建一个软链接
ln -s 目标文件名 软链接名//查看文件inode编号
ls -i上图可以看到软链接和目标文件使用的inode编号是不同的软链接具有独立的inode编号并且通过软链接mytest文件可以直接运行目标文件test软链接相当于一个快捷方式类似Windows系统其中所保存的内容是指向文件所在路径。
//创建一个硬链接
ln 目标文件 硬链接名硬链接不是独立的文件相当于一个指针指向某一个inode而硬链接数就是引用计数有几个硬链接指向该inode编号硬链接数就是几。
Linux中我们常见目录如下
. 当前目录
.. 上一级目录这两个目录就是硬链接软硬链接的区别软链接是一个独立的文件有自己独立的inode编号硬链接不是一个独立的文件它和目标文件使用的是同一个inode。
1.4 动静态库
静态库程序在编译链接的时候把库的代码链接到可执行文件中程序运行的时候将不再需要静态库静态库Linux下后缀为.a文件windows下后缀为.lib文件。动态库程序在运行的时候才去链接动态库的代码多个程序共享使用库的代码。动态库Linux下后缀为.so文件windows下后缀为.dll文件。在Linux下程序生成默认是动态连接。动态库可以在多个程序间共享所以动态链接使得可执行文件更小节省了磁盘空间。操作系统采用虚拟内存机制允许物理内存中的一份动态库被要用到该库的所有进程共用节省了内存和磁盘空间。
测试程序/add.h/#ifndef __ADD_H__#define __ADD_H__ int add(int a, int b); #endif // __ADD_H__/add.c/#include add.hint add(int a, int b){return a b;}/sub.h/#ifndef __SUB_H__#define __SUB_H__ int sub(int a, int b); #endif // __SUB_H__/add.c/#include add.hint sub(int a, int b){return a - b;}///main.c#include stdio.h#include add.h#include sub.hint main( void ){int a 10;int b 20;printf(add(10, 20)%d\n, a, b, add(a, b));a 100;b 20;printf(sub(%d,%d)%d\n, a, b, sub(a, b));}//生成静态库
ar -rc libmymath.a add.o sub.o
ar是gnu归档工具rc表示(replace and create)//查看静态库中的目录列表
ar -tv libmymath.a
t:列出静态库中的文件//gcc编译链接第三方库
gcc main.c -L. -lmymath
-L 指定库路径
-l 指定库名 将生成的静态库删除后程序依旧可以正常运行如下图
//生成动态库
//shared: 表示生成共享库格式
//fPIC产生位置无关码(position independent code)
//库名规则libxxx.so
gcc -fPIC -c sub.c add.c
gcc -shared -o libmymath.so add.o sub.o同样是上面的add.c和sub.c文件形成.o文件再生成一个动态库将动态库使用gcc编译main.c文件形成可执行文件在删除动态库之后此时与静态库不同该文件运行出错表示该动态库不存在。 那么链接静态库的时候为什么没有这个问题呢或者说链接动态库和静态库两者的区别是什么呢 静态链接是将所需要的库文件中的代码拷贝进我们自己的代码中然后再形成一个可执行程序运行时程序中已经包含了库中的代码不需要依赖库。与静态链接不同一个与动态库链接的可执行文件仅仅包含它用到的函数入口地址的一个表而不是外部函数所在目标文件的整个机器码在可执行文件开始运行以前外部函数的机器码由操作系统从磁盘上的该动态库中复制到内存中这个过程称为动态链接。 我们使用的库都是存放在磁盘上的文件动态链接的可执行程序运行时会将动态链接库加载到内存中加载到内存中的库代码只有一份进程通过页表将进程地址空间和库链接起来当使用动态链接库中的函数时会跳转到库中运行。