Linux知识点 -- 基础IO(三)

Linux知识点 – 基础IO(三)

文章目录

  • Linux知识点 -- 基础IO(三)
  • 一、理解文件系统
    • 1.磁盘文件
    • 2.文件系统的存储结构
    • 3.inode与文件名的关系
  • 二、软硬链接
    • 1、软链接
    • 2.硬链接
  • 三、动静态库
    • 1.库
    • 2.生成静态库
    • 3.静态库的使用
    • 4.生成动态库
    • 5.使用动态库
    • 6.为什么要有库


一、理解文件系统

1.磁盘文件

磁盘是永久性存储介质,如:SSD,U盘,光盘,磁带等;磁盘是外设,是我们计算机中唯一的机械设备,因此读取速度很慢;

  • 磁盘物理结构:
    在这里插入图片描述
    磁盘中有盘片、磁头、伺服系统、音圈马达等;
    磁盘面上会存储数据,由于计算机只认识二进制,因此用磁极来表示0和1,向磁盘写入,本质就是改变磁盘上的正负极;

  • 磁盘存储结构:
    在这里插入图片描述
    在这里插入图片描述
    磁盘中的每一个盘面都分为多个不同的磁道,每个磁道又分为不同的扇区,磁盘的最小存储单元是一个扇区大小是512byte

  • 如何将数据写入指定的扇区?
    这是磁盘的CHS寻址:
    (1)在哪一个面上;
    (2)在哪一个磁道上;
    (3)在哪一个扇区上;

  • 磁盘的抽象结构:
    我们将磁盘的磁道展开成为线性结构:
    在这里插入图片描述
    这样来看磁盘的结构就像是一个数组,访问一个扇区,只需要知道这个扇区的数组下标就好;
    我们平常所说的磁盘分区,就是将磁盘分为几个不同的数组:
    在这里插入图片描述
    将数据存储到该磁盘就变成了将数据存储到该数组;
    找到磁盘特定扇区的位置就变成了找到数组特定的位置;
    对磁盘的管理就变成了对数组的管理;

2.文件系统的存储结构

其中一个磁盘分区展开后的结构如下:
在这里插入图片描述
其中Blokck group就是用来存储文件的;
Linux在存储文件的时候,将内容和属性分开存储;
虽然磁盘的基本单位是扇区(512字节),但是操作系统(文件系统)和磁盘进行IO的基本单位是4KB(block的大小),因此,磁盘又被称为块设备;
这样设计的原因是:

  • IO基本单位设计的太小的话,会导致效率变低;
  • 如果OS使用和磁盘一样的基本单位,如果磁盘的基本单位更改了,那么操作系统也需要更改,所以需要对硬件和软件进行解耦;

在Blokck group中,有如下几个分区:

  • Super Block:存储整个分区的文件系统的属性信息;并不是每个快组都有SB模块,而是分发在分区中某几个快组中,为的是进行备份,防止丢失;
  • Group Descriptor Table(GDT)块组描述符,描述各个block的信息,如大小,使用情况,有多少inode等;
  • Block Bitmap:块组位图,其中的比特位和特定的block是一一对应的,如果该位为1,就表示该block已被占用,否则表示可用;
  • Inode Bitmap:inode位图,其中的比特位和特定的inode是一一对应的,如果该位为1,就表示该inode已被占用,否则表示可用;
  • Inode Table:inode是一个大小为128字节的空间,保存的是对应文件的属性,是该块组内,所有文件的inode空间的集合;需要标识唯一性,每一个inode块,都需要有一个inode编号,一般而言一个文件一个inode,一个inode编号;
  • Data blocks:多个4KB(扇区 * 8)大小的集合,保存的都是特定文件的内容;

格式化:将块组分割成上面的内容,并且写入相关的管理数据,每一个块组都如此操作,整个分区就被写入了文件系统信息;

一个文件可能对应多个block,找到文件,只需找到对应的inode编号,就能找到该文件的inode属性集合,文件内容所占的块组编号也在inode信息中的blocks数组中;
在这里插入图片描述
如果文件特别大,一个块组中放不下,需要存放到其他块组中,那么,inode中的blocks数组前m个block存放的是这个文件的数据,数组后面的block存放的是剩下数据存放的block块号,相当于一个间接寻址

3.inode与文件名的关系

  • Linux系统寻找文件的过程:
    由文件inode编号 -> 找到特定的bg块组 -> 对应的inode -> 属性 -> 内容;

那我们是如何得到文件的inode编号的?依托于目录结构;
Linux中,文件属性里面,没有文件名这样的说法;

  • (1)一个目录下,可以保存很多文件,但是这些文件没有重复的文件名;
  • (2)目录也是文件,有自己的inode,有自己的data block;

在Linux系统中存储文件,用户根据文件名创建和区分文件,但是写入系统时,系统只会为文件分配唯一的inode编号,然后建立文件名和inode编号的映射关系表,是一个KV结构,用户提供文件名,OS提供inode编号,所以用户能够通过文件名搜索到文件;

目录的权限:

  • 在目录中创建文件必须有写权限,是因为创建文件必须向目录写入该文件的文件名和inode的映射关系;
  • 显示文件名和属性必须有目录的读权限,因为要读取到文件的inode,才能读取属性

一个块组中,inode和data blocks的数量都是一定的,存在inode还有,但是block没了;或者inode没了,但是block还有的情况;

二、软硬链接

1、软链接

  • 创建软链接:
    在这里插入图片描述
    ln:创建链接;
    -s:软链接;

    ls -i指令能够看出文件的inode:
    在这里插入图片描述
    可以看到,软链接是有独立的inode的,是一个独立的文件;

  • 软链接的作用:
    在这里插入图片描述
    在bin/exe目录下的可执行程序test,在现在的目录下建立软链接:
    在这里插入图片描述
    直接运行软链接:
    在这里插入图片描述
    可以看出运行成功;
    软链接的文件内容,是指向对应文件的路径;可以理解为win下的快捷方式;

2.硬链接

  • 创建硬链接:
    在这里插入图片描述
    在这里插入图片描述
    可以看出,硬链接文件没有自己独立的inode,这也是软硬链接的本质区别;

  • 硬链接的作用:
    在这里插入图片描述
    从上图可以看出,硬链接和原文件属性中的这个数字都为2,这个属性是硬链接数
    硬链接就相当于给文件起别名,建立了文件名和指定inode的关系;
    当我们删除硬链接指向的文件时,硬链接inode还存在,属性中的硬链接数从2变成了1;
    在这里插入图片描述

硬链接没有独立的inode,不是一个独立的文件,创建硬链接,不是真正的创建新文件,就是在指定目录下,建立了文件名和指定inode的映射关系;
硬链接数就相当于一个引用计数,每创建一个硬链接时,引用计数就加一;当我们删除文件时,并不是把这个文件inode删除了,而是将这个文件的inode引用计数减一,当引用计数为0的时候,才真正删除;

  • 硬链接的用途:
    在这里插入图片描述
    新建一个普通文件,硬链接数是1;
    新建一个目录,硬链接数是2;

    在这里插入图片描述
    这是因为目录内部的 . 文件也影射了该目录的inode,两个硬链接,一个是自己的目录名链接inode,另一个是目录内部的 . 文件链接inode;
    在这里插入图片描述
    在test目录下再创建一个目录,可以发现test的硬链接数变为了3,这是因为ss目录中的 … 文件映射上级路径test的inode;

三、动静态库

1.库

  • 库中没有main函数;
  • 如果我只把.o和.h文件给别人,是可以使用的;
  • 静态库后缀为:.a;
  • 动态库后缀为:.so;

2.生成静态库

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
生成的.o文件给别人是直接可以使用的,但是很麻烦;
在这里插入图片描述
在这里插入图片描述
静态库的生成过程就是把.o文件打包的过程;
在这里插入图片描述

  • ar:归档文件;

  • -r:替换;

  • -c:创建;

  • libhello.a:静态库文件,必须以lib开头,.a结尾;

  • 使用makefile实现自动打包:
    在这里插入图片描述

  • 库的发布:
    库的发布文件夹里需要有两个子文件夹:
    -inlcude:保存库的独有头文件;
    -lib:保存对应的库文件;

    在makefile中完成自动化创建:
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

3.静态库的使用

在这里插入图片描述

  • (1)拷贝库文件到系统目录下:
    gcc头文件的默认搜索路径是:/usr/include
    gcc头库件的默认搜索路径是:/lib64 or /usr/lib64

    在这里插入图片描述
    这时main函数中不会报错,但是编译时会报错,因为这是我们自己提供的第三方库,必须要告知C语言我们需要连接哪个库;
    在这里插入图片描述
    -l库名:指定链接库(没有空格),真正的库名是去掉前缀lib和后缀的
    运行结果:
    在这里插入图片描述
    但是这种方法会污染官方库,不建议使用;

  • (2)让GCC在指定目录下搜索头文件和库:
    在这里插入图片描述
    -I 目录:在指令目录下搜索头文件;
    -L 目录:在指定目录下搜索库文件;
    由于该目录下可能有多个库文件,因此需要指定库文件;

    在这里插入图片描述
    在这里插入图片描述

4.生成动态库

在这里插入图片描述
在这里插入图片描述
-fPIC:生成一个与位置无关的目标二进制文件;
在这里插入图片描述
-shared:制作动态库,而不是可执行程序;

  • 用makefile实现:
    在这里插入图片描述
    动静态库一起生成,并发布output文件夹;
    在这里插入图片描述
    在这里插入图片描述
    打包库:
    在这里插入图片描述

5.使用动态库

在这里插入图片描述
从上面看出,直接使用gcc指定头文件和库文件的方法来加载动态库,能够编译过,但是无法运行程序,使用ldd命令查看动态链接时,发现libhello.so动态库链接找不到
ldd 可执行程序:查看该程序的动态链接;
我们发现gcc是默认动态链接的,但是没有链接上;
前面静态库是因为只有静态库,gcc只能静态链接:
在这里插入图片描述
使用静态库时就没有链接libhello.so;
-static:摒弃默认优先使用动态库的原则,直接使用静态库的方案;
在这里插入图片描述
在上面我们已经制定了动态库的路径,动态库还是无法链接,这是因为我们是给gcc指定的链接,这和动态库的加载过程有关;

  • 动态库的加载过程:
    动态库是一个独立的库文件,动态库和可执行程序,是可以分配加载的;
    静态库的加载是直接将库代码加载到了内存里面,直接进入进程的代码区;
    动态库是可以分批加载的,在将可执行程序加载到内存后,可执行程序中是有对应的库链接信息的;
    在编译链接时,需要加载库时,就可以加载动态库了,是分开进行的,这时再将动态库代码加载到内存中,在页表建立库代码与共享区的联系;
    在代码区函数跳转访问库函数的时候,直接跳转到共享区,根据页表找到内存中的库代码去执行;

    在这里插入图片描述

  • 方法一:添加环境变量
    我们上面指定动态库路径是给gcc指定的,动态库是运行时加载的,这时就与gcc没有关系了,需要给系统说;
    在这里插入图片描述
    $LD_LIBRARY_PATH是系统环境变量,加载库的路径;
    库的绝对路径:
    在这里插入图片描述
    导入环境变量:
    在这里插入图片描述
    运行可执行程序:
    在这里插入图片描述
    这种方法的缺点是:退出登陆后,环境变量会丢失,因为这是内存级的环境变量,只能做一个临时方案;

  • 方法二:修改配置文件
    在这里插入图片描述
    这个路径中包含自定义搜索库路径的永久解决方案;
    在这里插入图片描述
    直接创建文件,然后将目录放进该文件中;
    在这里插入图片描述
    在这里插入图片描述
    更新系统权限:
    在这里插入图片描述
    运行:
    在这里插入图片描述
    在这里插入图片描述

  • 方法三:在系统目录下建立软链接
    在这里插入图片描述
    运行:
    在这里插入图片描述

6.为什么要有库

  • 站在使用者的角度:
    库的存在,可以大大减少我们的开发周期,提高软件本身的质量;
  • 站在开发库的角度:
    简单,且能够保证代码安全;

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

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

相关文章

基于SpringBoot+Vue的在线考试系统设计与实现(源码+LW+部署文档等)

博主介绍: 大家好,我是一名在Java圈混迹十余年的程序员,精通Java编程语言,同时也熟练掌握微信小程序、Python和Android等技术,能够为大家提供全方位的技术支持和交流。 我擅长在JavaWeb、SSH、SSM、SpringBoot等框架…

Zabbix分布式监控Web监控

目录 1 概述2 配置 Web 场景2.1 配置步骤2.2 显示 3 Web 场景步骤3.1 创建新的 Web 场景。3.2 定义场景的步骤3.3 保存配置完成的Web 监控场景。 4 Zabbix-Get的使用 1 概述 您可以使用 Zabbix 对多个网站进行可用性方面监控: 要使用 Web 监控,您需要定…

matlab编程实践18、19

浅水方程 浅水方程可以建立起海啸和浴缸中波浪的数学模型。浅水方程建立了水或者其它不可压缩液体受扰动时传播的模型。隐含的假设是,液体的深度和波浪的长度、扰动等相比是很小的。 在这样的记号下,浅水方程为双曲守恒定律的一个例子。 使用拉克斯-冯特…

线段树详解 原理解释 + 构建步骤 + 代码(带模板)

目录 介绍: 定义: 以具体一个题目为例:​ 树的表示方法: 实现步骤: 构建结点属性: pushup函数: build函数: pushdown函数: modify函数: query…

『赠书活动 | 第十六期』《深入浅出Java虚拟机:JVM原理与实战》

💗wei_shuo的个人主页 💫wei_shuo的学习社区 🌐Hello World ! 『赠书活动 | 第十六期』 本期书籍:《深入浅出Java虚拟机:JVM原理与实战》 赠书规则:评论区:点赞&#xff…

站点可靠性工程 (SRE)

随着世界各地的组织努力开发安全、可靠、可扩展且可持续的 IT 基础架构,对高效基础架构监控和管理的需求日益增长,企业正在用不可扩展的遗留架构换取现代解决方案,在尖端技术的推动下,这些使基础设施管理过程更加顺畅和轻松&#…

SpringBoot + minio实现分片上传、秒传、续传

什么是minio MinIO是一个基于Go实现的高性能、兼容S3协议的对象存储。它采用GNU AGPL v3开源协议,项目地址是https://github.com/minio/minio。 引用官网: MinIO是根据GNU Affero通用公共许可证v3.0发布的高性能对象存储。它与Amazon S3云存储服务兼容…

C++设计模式之访问者模式

C访问者设计模式 文章目录 C访问者设计模式什么是设计模式什么是访问者设计模式该模式有什么优缺点优点缺点 如何使用 什么是设计模式 设计模式是一种通用的解决方案,用于解决特定的一类问题。它是一种经过验证的代码组织方式,可以帮助开发人员更快地实…

Linux——平台设备及其驱动

目录 前言 一、平台设备 二、平台驱动 三、平台驱动简单实例 四、 电源管理 五、udev 和驱动的自动加载 六、使用平台设备的LED 驱动 七、自动创建设备节点 前言 要满足 Linux 设备模型,就必须有总线、设备和驱动。但是有的设备并没有对应的物理总线&#x…

互联网被裁的程序员,未来有什么方向呢?

做了一份程序员“失业”后的自救方向汇总: 接下来挨个聊聊。 产品经理 都说产品和技术总是相爱相杀,不过产品和技术的关系也是最近的。 无论是产品转技术,还是技术转产品,相对来说都是比较容易的,很多底层逻辑是互通…

后端通过CorsRegistry对象配置了全局跨域,但是前端仍然报CORS跨域错误

后端通过CorsRegistry配置了全局跨域,但是前端仍然报CORS跨域错误 问题背景 在实现登录功能时,我先是通过CorsRegistry配置了全局跨域,然后配置了一个登录拦截器后前端就报错CORS跨域错误 问题原因 前置知识 首先我们来了解一下什么是跨域错误…

无脑入门pytorch系列(一)—— nn.embedding

本系列教程适用于没有任何pytorch的同学(简单的python语法还是要的),从代码的表层出发挖掘代码的深层含义,理解具体的意思和内涵。pytorch的很多函数看着非常简单,但是其中包含了很多内容,不了解其中的意思…

网络安全策略应包含哪些?

网络安全策略是保护组织免受网络威胁的关键措施。良好的网络安全策略可以确保数据和系统的保密性、完整性和可用性。以下是一个典型的网络安全策略应包含的几个重要方面: 1. 强化密码策略:采用强密码,要求定期更换密码,并使用多因…

Java类集框架(一)

目录 1.Collection集合接口 2.List 接口 (常用子类 ArrayList ,LinkedList,Vector) 3.Set 集合 接口(常用子类 HashSet LinkedHashSet,TreeSet) 4.集合输出(iterator , Enumeration) 1.Collection集合接口 Collection是集合中最大父接口,在接口中定义了核心的…

vue中各种混淆用法汇总

✨在生成、导出、导入、使用 Vue 组件的时候,像我这种新手就会常常被位于不同文件的 new Vue() 、 export default{} 搞得晕头转向。本文对常见用法汇总区分 new Vue() 💦Vue()就是一个构造函数,new Vue()是创建一个 vue 实例。该实例是一个…

Redis - 缓存的双写一致性

概念: 当修改了数据库的数据也要同时更新缓存的数据,缓存和数据库的数据要保持一致 那为什么会有不一致的情况呢? 如果不追求一致性,正常有两种做法 先修改数据库 后删除旧的缓存先删除旧的缓存 再修改数据库 我们以先删除旧的…

html学习9(脚本)

1、<script>标签用于定义客户端脚本&#xff0c;比如JavaScript&#xff0c;既可包含脚本语句&#xff0c;也可通过src属性指向外部文件。 2、JavaScript最常用于图片操作、表单验证及内容动图更新。 3、<noscript>标签用于在浏览器禁用脚本或浏览器不支持脚本&a…

华为数通HCIP-PIM原理与配置

组播网络概念 组播网络由组播源&#xff0c;组播组成员与组播路由器组成。 组播源的主要作用是发送组播数据。 组播组成员的主要作用是接收组播数据&#xff0c;因此需要通过IGMP让组播网络感知组成员位置与加组信息。 组播路由器的主要作用是将数据从组播源发送到组播组成员。…

第七篇:k8s集群使用helm3安装Prometheus Operator

安装Prometheus Operator 目前网上主要有两种安装方式&#xff0c;分别为&#xff1a;1. 使用kubectl基于manifest进行安装 2. 基于helm3进行安装。第一种方式比较繁琐&#xff0c;需要手动配置yaml文件&#xff0c;特别是需要配置pvc相关内容时&#xff0c;涉及到的yaml文件太…

软件测试面试真题 | 什么是PO设计模式?

面试官问&#xff1a;UI自动化测试中有使用过设计模式吗&#xff1f;了解什么是PO设计模式吗&#xff1f; 考察点 《page object 设计模式》&#xff1a;PageObject设计模式的设计思想、设计原则 《web自动化测试实战》&#xff1a;结合PageObject在真实项目中的实践与应用情…