Linux 基础IO [缓冲区文件系统]

news2024/11/25 6:29:18

 💓博主CSDN主页:麻辣韭菜💓

⏩专栏分类:Linux知识分享⏪

🚚代码仓库:Linux代码练习🚚

🌹关注我🫵带你学习更多Linux知识
  🔝

目录

前言

一.Linux下一切皆文件 

二.缓冲区

1.缓冲区概念

2.缓冲区意义 

3.缓冲区在哪里 

 三.文件系统

1.初识文件系统

2. 扇区中的块组是如何工作的?

3. 理解软硬链接 

 三.动静态库

生成静态库

生成动态库

​编辑 1.导入环境变量方法

 2.修改配置文件

 3.软连接到系统库下面


前言

基础IO讲了什么是fd,以及fd的本质是什么,系统调用接口。本篇重点缓冲区,理解文件系统,全面认识Linux下一切皆文件。

一.Linux下一切皆文件 

        如何理解一切皆文件?我们都知道Linux是用C语言写的,那时候的编程思想都是面向过程。C语言是如何实现面向对象?甚至是运行时 像C++一样有多态的特性?

底层的不同的硬件,一定是对应不同的操作方法,但是这些设备都是外设,所以这些外设核心访问函数,都可以是read、write I/O,因此这些设备,都有的自己的read、write 但是它们实现方法肯定是不一样的。所以从OS角度来讲,这些设备被打开时,OS给它们创建struct file结构体,不同的外设(对象)调用自己的读写函数。这不就形成多态了吗? 

二.缓冲区

1.缓冲区概念

什么是缓冲区?从生活角度来讲,最直观的就是快递公司,假如你在北京读大学,你高中的同学在新疆读大学,有一天你同学要给你寄新疆的特产。请问你同学给你寄东西是马上就发货的吗?如果是这样快递公司早就垮了。快递公司肯定是等到不同的人寄的东西,都是要发往北京 等到一车要装满之后,才发货。 这个车就是一段内存空间

2.缓冲区意义 

 为什么要有缓冲区? 从上面例子来说就是节约成本,对OS来说也是一样,大量频繁的IO访问对OS负担是很大的,这种模式我们叫做写透模式(WT),特点就是成本高,运行慢。

对用户而言建立缓冲区,写回模式(WB)快速,成本低。提高整机利用率。

3.缓冲区在哪里 

缓冲区在哪? 我们先看一段代码看看结果

int main()
{
    //c语言提供的
    const char *s = "hello world1\n";
    const char *s1 = "hello world2\n";
    printf("hello linux\n");
    fprintf(stdout, "%s", s);
    fputs(s1, stdout);
    //os提供的
    const char *s2 = "hello world3\n";
    write(1, s2, strlen(s2));

    //创建子进程
    fork();
    return 0;
}

我们对子进程进行重定向 发现除了write只写一次,C提供的函数写入了两次这是为什么? 

首先缓冲区的刷新策略先了解一哈:

1.立即刷新

2.行刷新

3.满刷新(全缓冲)

特殊情况:

•用户强制刷新(fflush)

•进程退出

一般C库函数写入文件时是全缓冲的 而写入显示器是行缓冲。当重定向到普通文件时数据缓冲方式就由行缓冲变为了全缓冲。

•而我们放在缓冲区中的数据,就不会被立即刷新,甚至fork之后,但是进程进程退出了,会统一刷新,写入到文件中。但是创建子进程的fork()调用会复制当前进程(父进程)的状态,包括程序计数器、寄存器内容、打开的文件描述符等。因此,在fork()之后,父进程和子进程都有自己的地址空间副本,但它们的程序执行路径是相同的。

•所以当你父进程准备刷新的时候,子进程也就有了同样的 一份数据,随即产生两份数据。
write 没有变化,说明没有所谓的缓冲。
综上: printf fwrite fputs 库函数会自带缓冲区,而 write 系统调用没有带缓冲区。另外,我们这里所说的缓冲区, 都是用户级缓冲区。其实为了提升整机性能,OS也会提供相关内核级缓冲区,不过不再我们讨论范围之内。 那这个缓冲区谁提供呢? printf fwrite fputs是库函数, write 是系统调用,库函数在系统调用的上层, 是对系统 调用的“封装,但是 write 没有缓冲区,而 printf fwrite 有,足以说明,该缓冲区是二次加上的,又因为是 C,所以由C 标准库提供。

 三.文件系统

1.初识文件系统

电脑中有没有没有被打开的文件?当然有的,在哪里?磁盘。

问题一:单个文件角度,这个文件在哪里,这个文件多大?这个文件其他属性是什么?

问题二:OS层面角度,一共有多少个文件?各自属性在哪里?如何快速找到?磁盘还可以存储多少个文件?如何快速找到指定的文件?

要像彻底明白上面的两个问题 我们需要先了解磁盘的物理结构。 

 

从上图可以看出磁盘并不是像光盘那样只有一面,它像是很多层的光盘叠放在一起,每一层都有一个读写磁头。 我们在看看盘面的俯视图。

 

2. 扇区中的块组是如何工作的?

        对于磁盘的每一个盘面来说,并不是所有的区域都可以用来存储数据,可以把扇区看作是C语言的中数组。每个一扇区的存储大小一般而言都是512字节。

        所以OS就把整个磁盘拆分成无数的扇区,就变成了无数的数组。所以要找到一个文件

就只需要找到它的下标。

        对磁盘的管理,变成了对数组的管理。那OS又是如何管理这些“数组”?

首先一个磁盘太大了,在我们电脑当中有C盘和D盘、E盘。这就是传说中分区。对磁盘的管理就变成了对一个小分区的管理。对分区在进行分,分成块组分治的思想管理 请看下图。

Block Group 文件系统会根据分区的大小划分为数个 Block Group 。而每个 Block Group 都有着相同的结构组成。
超级块( Super Block ):存放文件系统本身的结构信息。记录的信息主要有: bolck inode 的总量,未使用的block inode 的数量,一个 block inode 的大小,最近一次挂载的时间,最近一次写入数据的 时间,最近一次检验磁盘的时间等其他文件系统的相关信息。Super Block 的信息被破坏,可以说整个文件系统结构就被破坏了。
GDT Group Descriptor Table :块组描述符,描述块组属性信息。
块位图(Block Bitmap ): Block Bitmap 中记录着 Data Block 中哪个数据块已经被占用,哪个数据块没有被占用
inode 位图( inode Bitmap ):每个 bit 表示一个 inode 是否空闲可用。
节点表 (inodeTable)点表 : 存放文件属性 如 文件大小,所有者,最近修改时间等
数据区(Data blocks):多个4KB(扇区*8)大小集合。存放文件内容

块组被分成上面的相关内容,并且写入相关的管理数据,每一个块组都这么干,整个分区就被写入到了文件系统信息。这就是你电脑和手机每次重新安装系统所对应的传说之中的格式化。 

一个文件“只”对应一个inode属性节点,inode编号。(当然不是一个文件名叫张三,万一它有小名了?)一个文件只能对应一个block吗??

当然不是,在struct inode这个结构体中定义一个int block[15] 这样的数组  这个数组下标对应就是你文件的存放block,这样就找到了文件的内容。

文件属性?inode编号不就是文件的属性吗?

这时有人要问了 一个 int block[15] 才多大,能放下一个大文件吗?

不是所有的data block,只能存放文件数据,也可以存放其他块组的块号!!大文件不就放下了吗? 

 

3. 理解软硬链接 

        

inode 和 文件名 请问找到文件的本质什么?
inode编号 -> 分区特定的bg -> inode -> 属性 -> 内容 那怎么知道inode的编号?依托目录结构
所以我们看到,真正找到磁盘上文件的并不是文件名,而是inode。 其实在linux中可以让多个文件名对应于同一个inode
看下图

使用指令:ln 创建硬链接 

 

 可以发现,在创建硬链接前,myproc.cc的引用计数是1,而创建硬链接后计数变成了2,其实硬链接的本质就是给相同的文件取别名,硬链接没有自己的inode,它和原文件的inode相同!请看下面的图片验证:

 指令:ln -s 创建软连接

 可以发现,创建的软连接是独立的一个文件,它有自己的inode,那软连接有什么用?看下图演示。

 

如果一个大型项目,你要运行别人的写的函数,可是这个可执行程序不在你的当前路径,你要运行每次都要加路径,万一这个可执行程序隐藏的很深,那不是光加路径就烦人了,这时软连接就起作用了。 

 

 软链接就如同window下的快捷方式!!!

 三.动静态库

        

• 静态库(.a):程序在编译链接的时候把库的代码链接到可执行文件中。程序运行的时候将不再需要静态库
• 动态库(.so):程序在运行的时候才去链接动态库的代码,多个程序共享使用库的代码。
•一个与动态库链接的可执行文件仅仅包含它用到的函数入口地址的一个表,而不是外部函数所在目标文件的整个机器码 在可执行文件开始运行以前,外部函数的机器码由操作系统从磁盘上的该动态库中复制到内存中,这个过程称为动态链接(dynamic linking
•动态库可以在多个程序间共享,所以动态链接使得可执行文件更小,节省了磁盘空间。操作系统采用虚 拟内存机制允许物理内存中的一份动态库被要用到该库的所有进程共用,节省了内存和磁盘空间。

生成静态库

这是我写的两个简单函数,下面先生成.o文件

指令:g++ -c 文件名 -o 文件名.o 

第二步打包.o文件  指令:ar -rc libother.a add.o print.o

 

 这里指令太多了,直接用makefile

第三步发布  

 

 

指令:g++ main.cc -I ./other/include/ -L ./other/lib/ -l other 

 

静态库还有一种拷贝到系统环境下的方法,这里就不演示了,不推荐。

生成动态库

同时生成动态库和静态库 

 指令:g++ -c -fPIC add.cc -o add_d.o 

g++ -shared add_d.o print_d.o -o libother.so

-shared 是 g++ 编译器的一个选项,用于指示编译器生成共享对象文件(Shared Object File),这通常具有 .so 的扩展名。在Unix-like系统中,共享对象文件是一种可以被多个程序同时使用的库文件。这与静态库(通常由 ar 命令生成,具有 .a 扩展名)不同,静态库在链接时会被完整地复制到最终的可执行文件中。 当使用 -shared 选项时,g++ 会生成一个包含目标代码和重定位信息的共享对象文件。 

.PHONY:all
all:libother.so libother.a
libother.so:add_d.o print_d.o
	g++ -shared add_d.o print_d.o -o libother.so
add_d.o:add.cc
	g++ -c -fPIC add.cc -o add_d.o
print_d.o:print.cc
	g++ -c -fPIC print.cc -o print_d.o -std=c++11
libother.a: add.o print.o
	ar -rc libother.a add.o print.o
add.o:add.cc
	g++ -c add.cc -o add.o
print.o:print.cc
	g++ -c print.cc -o print.o -std=c++11

.PHONY:other
other:
	mkdir -p other/lib
	mkdir -p other/include
	cp -rf *.h other/include
	cp -rf *.a other/lib
	cp -rf *.so other/lib
.PHONY:clean
clean:
	rm -rf *.o *.a *.so other

 1.导入环境变量方法

运行出错了,找不到动态库 

导入环境变量:

export LD_LIBRARY_PATH=$LD_LIBART_PATH:/home/gx/linux-exercise/lesson9/uselib/other/lib

 

 2.修改配置文件

/etc/ld.so.conf.d/ 在这个路径下创建一个文件 other.conf

 

sudo vim 打开这个文件 

 

粘贴复制之后 再sudo ldconfig 

这时我们再./a.out就找到这个库了。

 

 3.软连接到系统库下面

指令:这里软连接要用绝对路径

sudo ln -s ~gx/linux-exercise/lesson9/uselib/other/lib/libother.so /lib64/libother.so

 

不推荐这个做法,因为我们写的这个库是没有经过官方认证的,这样会污染官方库。

下去自己试了之后就把它删除了。 

 

还有没有其他方法,当然还有的,.bashrc 这里 把我们第一点方法放在这里就行。

建议不要做!!!

下节预告进程间通信 ,关注我带你学习更多Linux知识。

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

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

相关文章

调试技巧安全预编译头文件(C++基础)

调试 调试可以选择条件调试和操作调试: 条件调试来选择条件进入断点设置,操作调试来使达到断点条件后完成某些操作(一般是output窗口输出)。 在这里就只输出了小于6的条件。 安全 降低崩溃、内存泄露、非法访问等问题。 应该转…

vue基础教程(5)——构建项目级登录页

同学们可以私信我加入学习群! 正文开始 前言一、创建首页二、登录页代码讲解三、对应的vue知识点:四、附件-各文件代码总结 前言 前面我们已经把vue自带的页面删除,也搭建了最简单的router路由,下面就可以真正开发我们自己的项目…

蓝桥杯-python-常用库归纳

目录 日期和时间 datetime模块 date日期类,time时间类,datetime日期时间类 定义date(年,月,日) data之间的减法 定义时间(时,分,秒) 定义datetime&#xf…

文献学习-23-MRM:用于遗传学医学图像预训练的掩码关系建模

MRM: Masked Relation Modeling for Medical Image Pre-Training with Genetics Authors: Qiushi Yang, Wuyang Li, Baopu Li, Yixuan Yuan Source: ICCV 2023 Abstract: 关于自动多模态医疗诊断的 ODERN 深度学习技术依赖于大量的专家注释,这既耗时又令人望而却…

DeepL Pro3.1 下载地址及安装教程

DeepL Pro是DeepL公司推出的专业翻译服务。DeepL是一家专注于机器翻译和自然语言处理技术的公司,其翻译引擎被认为在质量和准确性方面表现优秀.DeepL Pro提供了一系列高级功能和服务,以满足专业用户的翻译需求。其中包括: 高质量翻译&#xf…

Python 常用内置库 time库、random库、turtle库

文章目录 一、time库二、random库三、turtle库1. 绘制正方形2. 使用海龟对象绘制六边形3. 绘制多个起点相同大小不同起点的五角星4. 绘制多个图形和添加文字 提示:以下是本篇文章正文内容,下面案例可供参考 一、time库 time是最基础的时间处理库&#…

系统慢查询的思考

系统慢查询的思考 在一个系统中发现慢查询的功能或很卡的现象。你是怎么思考的?从哪几个方面去思考?会用什么工具? 一个系统使用了几年后都可能会出现这样的问题。原因可能有以下几点。 数据量的增加。系统中平时的使用中数据量是有一个累…

HTML块级元素和内联元素(头部和布局)

目录 1.HTML块级和内联标签: 1.块级元素: 2.内联元素: 3.元素嵌套: 4.元素转换: 示例如下: 2.内联框架: 前言: 示例如下: 3.布局: 4.头部标签: 前言: 说明&…

GT收发器PHY层设计(3)PHY层设计

文章目录 前言一、设计框图二、PHY层基本传输协议三、PHY_TX模块3.1、模块接口3.2、组帧状态机描述3.3、数据大小端问题3.4、字节对齐 四、PHY_RX模块4.1、模块接口4.2、大小端转换4.3、起始位4.4、结束位4.5、axis数据流恢复 五、LFSR伪随机码六、链路空闲时期处理 前言 上一…

windows平台虚拟机安装

windows平台虚拟机安装 1. 安装VMwareWorkstationPro 1.1 软件下载 官网下载 官网 百度网盘下载 版本 VMwareWorkstationPro16 链接:https://pan.baidu.com/s/1LidMxoM9e4a4CANixyRoyg?pwd1157 提取码:1157 1.2 软件安装 软件安装注意事项 软件…

类的新功能

类的新功能 默认成员函数 在C11之前,一个类中有如下六个默认成员函数: 构造函数。拷贝构造函数赋值重载析构函数取地址重载函数const取地址函数 其中前四个默认成员函数最重要,后面两个默认成员函数一般不会用到,这里默认成员…

Js之运算符与表达式

运算符:也叫操作符,是一种符号。通过运算符可以对一个或多个值进行运算,并获取运算结果。 表达式:由数字、运算符、变量的组合(组成的式子)。 表达式最终都会有一个运算结果,我们将这个结果称…

从输入url到页面展示的过程

唠唠叨:我不想误人子弟,我这篇算是搬运工,加上自己的理解做点总结,所以还请大家科学上网去看这篇:https://aws.amazon.com/cn/blogs/mobile/what-happens-when-you-type-a-url-into-your-browser/ 是这六个步骤&#…

springboot论坛管理系统

论坛管理系统 摘要: 在社会快速发展的影响下,论坛管理系统继续发展,使论坛管理系统的管理和运营比过去十年更加信息化。依照这一现实为基础,设计一个快捷而又方便的网上论坛管理系统是一项十分重要并且有价值的事情。对于传统的论…

如何提升公众号搜索量?分享内部运营的5步优化技术!

最近一直有自媒体同行朋友在写关于公众号的内容,很多都说公众号现在没得玩了。其实,在运营自媒体上面,思维不通,技术不到位,哪个平台都不适合你玩。 想要在自媒体上面运营变现,一定不要先点击广告变现&…

【Linux】详解文件系统以及周边知识

一、磁盘的基本知识 磁盘中可以被划分成一个一个的环,每个环都是一个磁道。每个磁道又可以被均分成一个一个的扇区,扇区是磁盘IO的基本单位(想要修改扇区中的一个比特位就必须把该扇区的全部比特位都加载到内存中)。磁盘中的盘面&…

「MySQL」索引事务

🎇个人主页:Ice_Sugar_7 🎇所属专栏:数据库 🎇欢迎点赞收藏加关注哦! 索引&事务 🍉索引🍌特点🍌通过 SQL 操作索引🍌底层数据结构 🍉事务&…

张颂文|永远保持好奇心的人,是永远进步的人。

哈喽,你好啊,我是雷工! 今天看到了张颂文的一段演讲,提到了他因为好奇心而被改变的人生。 如果想把单一和枯燥的工作做的更好,张颂文的办法是像一个孩子一样保持好奇心,不停地提出一些有趣的问题。 在5年的导游经历中,对每次游览的地点都像初次游览般保持好奇心,正因为…

C++从入门到精通——引用()

C的引用 前言一、C引用概念二、引用特性交换指针引用 三、常引用保证值不变权限的方法权限的放大权限的缩小权限的平移类型转换临时变量 四、引用的使用场景1. 做参数2. 做返回值 五、传值、传引用效率比较值和引用的作为返回值类型的性能比较 六、引用和指针的区别引用和指针的…

工单系统的作用与优势!为什么企业需要它?

什么是工单系统?工单系统作为企业服务类工具,能在管理上和业务上为企业带来什么帮助吗? 什么是工单系统 ZohoDesk工单系统是一种用于管理和处理任务或请求的软件工具。它提供了一个集中的平台,使组织能够跟踪、分配和解决各种问题、请求和…