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

 💓博主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.og++ -shared add_d.o print_d.o -o libother.so
add_d.o:add.ccg++ -c -fPIC add.cc -o add_d.o
print_d.o:print.ccg++ -c -fPIC print.cc -o print_d.o -std=c++11
libother.a: add.o print.oar -rc libother.a add.o print.o
add.o:add.ccg++ -c add.cc -o add.o
print.o:print.ccg++ -c print.cc -o print.o -std=c++11.PHONY:other
other:mkdir -p other/libmkdir -p other/includecp -rf *.h other/includecp -rf *.a other/libcp -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.mzph.cn/news/777445.shtml

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

相关文章

在线接口文档预言方案

在线接口文档预言方案 要求: ​ 支持自动生成接口文档 ​ 能够支持在线测试(http,websocket) ​ 对代码没有侵入性 一、目前涉及的相关技术收集 sudo apt update #更新数据 sudo apt upgrade #更新软件 sudo apt install openssh-server #下载安装…

数据结构与算法-分治算法

数据结构与算法 数据结构与算法是计算机科学中的两个核心概念,它们在软件开发和问题解决中起着至关重要的作用。 数据结构 数据结构是计算机中存储、组织和管理数据的方式,它能够帮助我们高效地访问和修改数据。不同的数据结构适用于不同类型的应用场…

14.黑盒测试

黑盒测试、白盒测试考题固定,重视!!! 等价类、边界值、场景法;考察频率高!!! 因果图,偶尔考;要能看懂因果图,结合题干填写缺失的部分内容&#x…

Redis中的客户端(三)

客户端 身份验证 客户端状态的authenticated属性用于记录客户端是否通过了身份验证: typedef struct redisClient {// ...int authenticated;// ... } redisClient;如果authnticated的值为0,那么表示客户端未通过身份验证;如果authenticated的值为1&a…

智慧酒店(二):AI智能分析网关V4视频分析技术在酒店管理中的应用

一、人工智能技术如何应用在酒店管理中? 随着科技的飞速发展,人工智能技术已经逐渐渗透到我们生活的方方面面,其中,酒店管理行业便是其应用的重要领域之一。人工智能技术以其高效、精准的特点,为酒店管理带来了革命性…

Day34:学习尚上优选项目

学习计划:完成尚硅谷的尚上优选项目 学习进度:尚上优选项目 知识点: 四、 搭建平台管理端前端环境 改造登录功能功能测试 权限管理模块-角色管理 环境搭建开发角色管理接口 权限管理模块-用户管理 开发用户管理CURD接口

题目 2894: 肿瘤检测

题目描述: 一张CT扫描的灰度图像可以用一个N*N&#xff08;0 < N < 100&#xff09;的矩阵描述&#xff0c;矩阵上的每个点对应一个灰度值&#xff08;整数&#xff09;&#xff0c;其取值范围是0-255。我们假设给定的图像中有且只有一个肿瘤。在图上监测肿瘤的方法如下…

31-4 命令执行漏洞 - RCE原理

一、定义 RCE(远程命令/代码执行)漏洞是指存在于软件或系统中的安全漏洞,使得攻击者可以通过网络远程执行操作系统命令或者注入恶意代码,从而控制目标系统。 二、漏洞原理 漏洞原理是指RCE漏洞产生的根本原因,通常与不安全的输入验证、错误的配置和不充分的安全措施有关…

修改nuxtjs项目中的浏览器图标步骤

处理步骤&#xff1a; 打开配置页面 使用el-upload 上传图片到后台 后台把图片转为ico&#xff0c;返回图标路径 配置页面修改本页面预览图&#xff0c;点击保存&#xff0c;修改的数据库。 通知nuxt布局页面&#xff0c;修改head节点中的图标属性&#xff0c;…

如何系统得自学python?——7.列表与元组

列表 一、列表的应⽤场景 列表是Python中最常用的数据结构之一&#xff0c;用于存储一组有序的数据。它在各种场景中都有广泛的应用&#xff0c;例如&#xff1a; 存储多个相同类型的数据&#xff0c;如学生成绩、员工工资等。存储不同类型的数据&#xff0c;如图书信息&…

Channel 结合 Select 使用

在Go语言中&#xff0c;channel和select结合使用是一种强大的并发模式。channel允许在不同的goroutine之间安全地传递消息&#xff0c;而select使得goroutine可以同时等待多个通信操作&#xff08;channel操作&#xff09;。 select语句等待多个channel操作中的任意一个完成。…

《VulnHub》Lampião:1

title: 《VulnHub》Lampio&#xff1a;1 date: 2024-03-28 21:37:49 updated: 2024-03-28 21:37:50 categories: WriteUp&#xff1a;Cyber-Range excerpt: 关键技术&#xff1a;主机发现&#xff0c;端口扫描、服务探测、操作系统探测&#xff0c;对开放的端口探测漏洞&#x…

寒冬继续!飞书发全员信 “适当精简团队规模”

多精彩内容在公众号。 3月26日飞书CEO谢欣发布全员信&#xff0c;宣布进行组织调整&#xff0c;同时为受到影响的“同学”提供补偿方案和转岗机会。 在致员工的一封信中&#xff0c;谢欣坦诚地指出&#xff0c;尽管飞书的团队人数众多&#xff0c;但组织结构的不够紧凑导致了工…

fastadmin学习05-开启debug以及配置

FastAdmin 框架提供了对 .env 环境变量配置的支持&#xff0c;并附带一个默认示例文件 .env.sample。在安装后&#xff0c;框架并不会自动启用 env 环境变量&#xff0c;需要手动将 .env.sample 复制为 .env 并进行配置。 如果不开启.env会读取database.php中的配置 下面测试…

redis缓存穿透、缓存击穿、缓存雪崩及其解决方法

缓存穿透、缓存击穿、缓存雪崩是redis的三大问题。 在介绍这三大问题之前&#xff0c;我们需要先了解Redis作为一个缓存中间件&#xff0c;在项目中是如何工作的。首先看一下在没有缓存中间件的时候的系统数据访问的架构图&#xff1a; 客户端发起一个查询请求的时候&#xff…

Maya 2024 for Mac/Win:重塑三维创意世界的利器

在数字化浪潮汹涌的当下&#xff0c;三维图形软件早已成为创意产业不可或缺的重要工具。而在这其中&#xff0c;Maya 2024以其卓越的性能和丰富的功能&#xff0c;赢得了无数设计师的青睐。无论是Mac还是Win平台&#xff0c;Maya 2024都能为您的三维创作提供强大的支持。 Maya…

【ssh免密设置】

本机远程的服务器上执行&#xff1a; ssh-keygen -t rsa2.然后修改公钥的权限&#xff08;xxxxx.pub需要替换&#xff09; chmod 600 xxxxx.pub3.再执行命令&#xff0c;将公钥导到免密的服务器上&#xff08;服务器ip地址替换成自己的&#xff09; ssh-copy-id root服务器i…

算法系列--动态规划--背包问题(2)--01背包拓展题目

&#x1f495;"2024.3.28小米汽车发布"&#x1f495; 作者&#xff1a;Lvzi 文章主要内容&#xff1a;算法系列–动态规划–背包问题(2)–01背包拓展题目 大家好,今天为大家带来的是算法系列--动态规划--背包问题(2)--01背包拓展题目 1.分割等和⼦集 链接: https:/…

史上最全-Java面试题(涵盖基础、高级、框架、微服务、中间件、大厂真题等28个大类超3000+面试题,全部附带详细答案)

3月4月又到了一年一度的跳槽黄金期,无论几年经验,也无论技术能力如何,跳槽前都离不开面试准备,其中刷面试题是重中之重。 刷面试题的时候一大痛点就是太分散了,需要自己根据知识点一项一项的去搜,容易遗漏知识点而且面试题质量无法保证,非常痛苦,基于此我花了两个月的…

微信小程序修改checkbox和radio的样式

我们在开发小程序的时候&#xff0c;有时候需要修改小程序中checkbox和radio的原生样式&#xff0c;如何修改呢&#xff1f;这里给大家提供了一份代码&#xff0c;大家可以试试。 首先是修改checkbox样式的代码&#xff1a; /* 重写 checkbox 样式 */ /* 未选中的 背景样式 *…