超市网站建设策划书,做视频投稿赚钱的网站好,团购酒店的网站建设,商标设计网上接单 平台文章目录1、磁盘结构1.1 磁盘的物理结构1.2 磁盘的存储结构1.3 磁盘的逻辑结构2、文件系统2.1 4KB加载到内存2.2 文件系统结构3、软硬链接3.1 软链接3.2 硬链接4、动静态库4.1 什么是库#xff1f;4.2 静态库和静态库链接4.3 动态库和动态库链接4.4 动静态库的加载下面了解到4.2 静态库和静态库链接4.3 动态库和动态库链接4.4 动静态库的加载下面了解到操作系统是如何管理放在磁盘中的未打开文件的。 1、磁盘结构 磁盘不仅是一种外设还是唯一的一个机械结构的外设所以相对其它硬件来说很慢但是它可以存储大量的数据下面看它的具体结构。 1.1 磁盘的物理结构 磁盘主要由盘面、磁头等构成。 值得注意的是 磁盘的盘面有两面两面都可以读写数据一个磁盘有多个盘面。 磁盘的磁头每个盘面的一面都对应着一个磁头并且磁头和盘面是没有挨着的。这点不像老式DVD读光盘是挨着的 磁盘的存储原理在大概上 盘片中有很多微小的磁块这些磁块拥有着南北极存储对应的二进制01。磁头对磁块进行放磁使得磁块进行转向通过南北极转换来进行01二进制标识。 1.2 磁盘的存储结构 在盘面上每一圈对应着一个磁道磁道又分为多个扇区。 磁头是共进退的磁头在定位对应盘面的时候整体是共进退的所以磁头共同在同一个磁道上找整体就成了柱面。 对于扇区来说靠圆心的扇区面积小离圆心远的扇区面积大但是每个扇区都是512byte密度不一样。当然也有一样的这里是一般的。 磁盘的寻址方式的基本字节是512byte一个扇区大小。 那么磁盘中如何定位一个扇区呢 先在整个柱面Track定位哪一个磁道再定位磁头(head)看在哪个盘面上最后定位在哪个扇区(sector)上。综上这个方法也叫CHS。 磁头来回摆动确定在哪个磁道盘面高速旋转让磁头定位扇区。 所以磁盘效率就看在高速旋转中在能读写数据的前提多少转每秒即每秒多少读写次数。 1.3 磁盘的逻辑结构 磁盘在物理上的存储结构是圆形的如果将其抽象拉直就变成了对数组的管理。 在数组上分为多个大的磁道磁道中又分了多个扇区所以只要通过简单的除与除余就能得到一个扇区的位置。这种定位也被称为LBAlogical block address 这种方式相较于CHS法有什么好处吗 1、首先这样肯定是更加方便管理的。 2、其次OS不想和硬件进行强耦合这个方式在OS中可以不仅限于管理磁盘也能用在其它硬件上。 2、文件系统
2.1 4KB加载到内存 首先前面说过磁盘在读取时基本单位是512byte但是对于OS来说一次读这么点还是太少了OS就有自己的读取策略一次读取多个扇区比如1KB、2KB、3KB、4KB现在主流都是一次4KB。 在一次读多个扇区下哪怕是访问一个字节的量也要将4KB空间load到内存。 这种方式也有部分因为局部性原理 当计算机访问数据附近的数据也大概率被访问到。加载更多的数据能增加数据IO的效率局部性原理的存在也能增加数据的命中率一定上减缓了更多的IO过程本质是一种数据预加载空间换时间 内存也因此被划分成了多个4KB大小的空间这个空间称为页框一个4KB大小的块被称为页帧。 2.2 文件系统结构
磁盘是很大的为了更好的管理需要分区分组 与国家划分省、市是一样的但磁盘有一点不太的是各个分区分组的管理方式是一样的。 超级块Super Block存放文件系统本身的结构信息有属性信息、磁盘布局和资源使用情况等信息。超级块属于整个分区分区有一定比率分组都有对应的超级块多存在意味着备份保存在不同分组若某一个分组的文件系统坏了可以用其它分组的超级块恢复。块组描述符GDT存放分组的宏观属性信息如一共有多少个inode有多少数据块以及用了多少多少没被用。 首先一个文件 内容 属性并且文件的内容和属性是分开存储的 其中文件内容保存在数据块中Data Blocks文件属性保存在Inode中。 Inodeext3-128byte ext4-256byte包括一个文件的几乎所有属性文件名不在Inode中并且每个文件都有属于自己的Inode。 通过ls -li 带上-i 可以查看每个文件对应的Inode。 Inode Table 保存了分组内部所有可用使用和未使用的inode。Data blocks 保存的是分组内部所有文件的数据块4KB为单位
为了区分Inode或者Data blocks 中哪些被使用哪些没被使用。
Inode Bitmap 中inode通过位图结构一个Inode对应一个bit位比如第一个bit位代表1号inode1代表被用0代表没被占用。Block bitmap 数据块对应的位图结构也一样比如10000个块对应10000个bit位被使用的块由0置1清除就由1置0。 当想查找一个文件时统一使用的是: inode编号 并且Inode在不同组有多套inode比如0组是1000开始的1组是10000开始的所以拿到一个inode也很好定位 值得注意的是我们使用的是文件名不是inode这是因为目录也是个文件目录的数据块存的是目录里文件的inode和文件名的映射所以通过文件名再到映射的inode就可以找到了。 这也说明一个目录下不能有同名文件。 也说明如果要在目录创建一个文件必须有目录的写入权限需要在目录代码块中建立inode和文件名的映射。 那如何找到文件内容呢数据块这么多怎么知道是你的 在inode属性中有一个blocks数组其中0-11一般指向一个数据块如果文件只有几个数据块直接通过下标定位对应数据块就行了。 一般从12、13、14开始比如12指向的数据块里面保存着其它数据块的地址。13、14指向的数据块里面指向有多层都是地址这样就可以指向很多给数据块。 那么如何删除文件呢 直接通过inode找到对应代码块将代码块对应的block bitmap中1置0再将inode bitmap中对应的inode置0就行。 这就说明删除文件只是把bitmap中至0对应数据块的数据还是在的 如果误删文件只是清bit位恢复文件Inode bitmap至1inode table中找数据块映射将对应block bitmap中至1就能找回文件所以如果误删文件最好就是什么也别做怕将原来数据块覆盖。 3、软硬链接
3.1 软链接 首先通过ln -s 文件名 生成软链接文件名 比如下面创建一个soft_file.link。 软链接的原理 软链接是一个独立的文件只不过这个文件保存着被链接文件的地址。 当被链接文件删除时这个地址也就无效了简单来说软链接生成的文件就是一个快捷方式。 可以看到软链接生成的文件有自己的inode
通过unlink 链接文件名 或者 rm 就可以删除链接文件取消软链接。 3.2 硬链接 硬链接通过 ln 被链接文件名 生成链接文件名比如 可以看到生成的链接文件和被链接文件用的是同一个inode 因为目录中存在两个不同的文件名映射同一个inodeinode里也会有一个计数器计数有多少个文件名和inode映射关系引用计数硬链接数 如果删除了mytest.txt仅仅减少一个引用计数和一个对应关系。 只有当引用计数为0时位图才清0文件才删除。 下面两个文件名链接到同一个inode所以各自硬链接数为2 硬链接的作用 首先对于一个普通文件硬链接数为1因为只有自身文件名和inode具有映射关系。 一个目录默认硬链接为2因为本身和inode有映射关系而在目录中 . 作为一个文件代表当前目录和目录有一样的inode是目录的硬链接。 下面又在empty目录里再创一个目录empty2此时empty的硬链接数为3这个empty2中的…文件是empty目录的硬链接。 综上硬链接让文件系统能够方便的访问上下文。 下面看到的一个问题 Linux 为什么不允许用户包括root给目录建立硬链接呢 .和… 不就是给目录建立的硬链接吗 其实这时操作系统给的保护措施操作系统只运行自己建立不允许使用者建立。 怕的就是这样 4、动静态库
4.1 什么是库
首先得了解一下编译的过程及命令 -o 指明形成的临时文件名 .o文件结尾的叫做可重定义目标二进制文件。 gcc -E test.c -o test.i 预处理 gcc -S test.i -o test.s 编译 转换成汇编语言 gcc -c test.s -o test.o 汇编转换成不可执行的二进制文件 gcc test.o -o mytest 链接 分别记忆成ESc和iso 在实际生成一个文件可以不用从预处理写起比如生成一个不可执行的二进制文件可以直接gcc -c 指定文件名 如果不想给对方源代码(.c)文件只需要给对方编译好的.o可重定义目标二进制文件再包括对应头文件就行。 .o文件包括方法的实现.h文件包括有什么方法 将所有.o文件打一个包给对方提供一个库文件即可 综上库其实就是多个.o文件的集合。 4.2 静态库和静态库链接 生成静态库 比如ar -rc libmymath.a add.o sub.o (rc表示replace and create) 将add.o和sub.o打包成libmymath.a静态库文件。 查看静态库中的目录列表: 比如ar -tv libmymath.a -t 列出静态库中的文件v:verbose 详细信息 除了要静态库文件还要对应匹配的头文件将库文件和.h打包起来并且可以通过压缩包让别人使用而安装本质就是将头文件和.a文件拷贝到系统特定路径。 特定的头文件就是放在user/include下特定动静态库就是放在/lib64下
这里的测试文件就不放在系统特定文件中这里可以自己创建一个mylib。 再将静态库文件和头文件打包让使用者只能获取函数使用。 接下来就是链接库生成可执行文件的过程 值得注意的是平常程序生成可执行文件的命令简略是因为默认指明了库文件的路径以及头文件的路径。 这里的链接就需要自己指明各自的库路径。 gcc -o mymath main.c -I ./mylib/include -L ./mylib/lib -l mymath (其中-o指明生成的可执行文件名-l 指明include文件路径-L 指明lib文件路径-l 指明库文件名) 最重要的是库文件名其实是libmymath.a但是在链接时需要去掉lib和后缀.a才是真正文件名。 测试目标文件生成后静态库删掉程序照样可以运行 4.3 动态库和动态库链接 生成动态库 比如gcc -fPIC my_add.c 生成与位置无关码的.o文件。 生成多个.o文件后。 通过gcc -shared -o libmymath.so my_add.o my_sub.o生成动态库文件。 生成动态库文件后将库文件和头文件进行打包。 打包后如果正常链接也是会出错的意料之中因为没有指明库文件路径和头文件路径 指明路径后成功生成可执行文件但是运行却发生了错误。 通过ldd列出动态库依赖关系看到libmymath.so 动态库的地址找不到。 为什么会找不到动态库 因为上述操作只告诉了gcc库文件路径和名称但是程序在gcc编译完后就和gcc没关系了变成进程和系统的关系了所以也要告诉OS和shell库文件的路径和名称。 一般动态库也是在lib64下的我的库没有在系统路径下所以OS无法找到 OS搜索库除了放在特定目录下还可以在环境变量中搜索 比如:echo $LD_LIBRARY_PATH 将动态库绝对路径放入export LD_LIBRARY_PATH$LD_LIBRARY_PATH:/home/yzh/dslib/test/mylib/lib/ 这种方法如果用户退出就失效了。 如果要永久有效的话。 只要访问cd /etc/ld.so.conf.d/这个路径在这个路径下创建一个配置文件然后将我们的动态库的绝对路径放入任意一个配置文件当中就可以了。 sudo创建一个配置文件再sudo vim打开放入路径。 放入后sudo ldconfig 更新配置文件 最后一种方式就是通过软链接在自定义路径下创建一个动态库的快捷方式。 4.4 动静态库的加载
静态库的加载 静态库的加载很简单静态库的代码在编译期间直接拷贝到程序的代码区未来这部分代码必须通过相对确定的地址位置来进行访问这也使得这部分代码在编译期间就有了一套虚拟地址可以和虚拟地址空间进行适配。绝对编址方案 动态库的加载 动态库是将指定函数的地址写入到可执行程序中。 1、动态库中的函数在编译期间是以一种start偏移量方式定位的函数只需要填一个偏移量地址。start就是ldd指令显示的动态库起始地址偏移量是相对start的所以在gcc -fPIC 形成与位置无关码就是想用偏移地址不是绝对编地址。 2、当程序加载到内存并且走到函数时这个时候就会停下来访问动态库所以也是为什么要让OS看到动态库然后将动态库需要的部分加载到内存中映射到共享区这个时候就获得了库的起始地址这样函数就可以通过偏移量访问对应函数。 综上 1、如果有很多个程序并且有很多用着同一份函数如果链接的是静态库就有着相同份的函数加载到内存如果链接动态库就只需要加载一份函数到内存能很好的节省资源。 2、其实gcc是默认建议是动态链接的一个可执行文件如果链接了很多个库有静态和动态的多个库是一个一个链接的如果是动态库就动态链接静态就静态链接但是如果有一个动态库那么整个链接就是动态链接。这也是为什么静态链接后查看文件链接类型还是动态链接因为还动态链接了C库。 本章完~