当前位置: 首页 > news >正文

泛华建设集团有限公司网站上海小程序定制公司

泛华建设集团有限公司网站,上海小程序定制公司,wordpress 中英文双语,收录提交#x1f431;作者#xff1a;一只大喵咪1201 #x1f431;专栏#xff1a;《Linux学习》 #x1f525;格言#xff1a;你只管努力#xff0c;剩下的交给时间#xff01; 基础IO☕理解缓冲区#x1f9c3;缓冲区的共识#x1f9c3;缓冲区的位置#x1f9c3;缓冲区的刷… 作者一只大喵咪1201 专栏《Linux学习》 格言你只管努力剩下的交给时间 基础IO☕理解缓冲区缓冲区的共识缓冲区的位置缓冲区的刷新策略简单模拟用户缓冲区☕理解文件系统认识磁盘文件管理操作未被打开文件☕总结☕理解缓冲区 缓冲区的共识 缓冲区存在的现象 在我们写的第一个Linux程序中当时就存在一个刷新缓冲区的操作为了能够在屏幕上立刻打出我们要输出到内容如下图所示。 还有在使用C语言scanf函数的时候为了不让空格影响获取字符串经常会使用getchar把空格字符串跳过而且并没有接收getchar的返回值仅仅是为了从缓冲区中将空格拿走。 在我们学习的过程中种种迹象表明是存在缓冲区的但是它具体是什么一直都没有一个答案今天本喵就给大家详细介绍一下缓冲区。 缓冲区存在的意义 当一个进程要向文件中写入数据的时候有两种方案 进程直接将数据写入到文件中如上图中蓝色箭头所示。进程将数据写入到缓冲区中然后再由缓冲区将数据写入到文件中如上图黑色箭头所示。 这里两种方式哪种好呢看起来像是第一种方案好因为比较简单数据直接从进程流向文件就行但事实上不是这样。 第一种方案中无论是在向磁盘上的文件写入数据还是向显示器等其他硬件写入数据都需要很长的时间因为硬件的访问相对于CPU的速度来说是非常慢的此时CPU就需要进行等待。第二种方案中将数据写入到缓冲区中缓冲区的访问速度肯定要比访问硬件快的多数据写入到缓冲区以后CPU就可以去干其他的事情了而缓冲区中的数据会由操作系统在合适的时间写入到文件中。 从上面的分析可以得出结论缓冲区的存在是为了给发送方节省时间。 既然缓冲区的存在是为了给CPU节省时间那么它的访问速度肯定是比文件要快的多的所以它只能是内存。所以说缓冲区本质上就是一段内存。 缓冲区的位置 既然缓冲区是一段内存那么这段内存是谁申请的它是属于谁的 来看一个现象 如上图所示的代码使用C语言提供的打印函数和系统调用输出重定向到log.txt文件中发现各个接口只调用了一次。 在程序执行完毕但是进程没有结束的时候使用fork创建子进程再将运行结果输出重定向到log.txt文件中发现C语言提供的接口调用了两次而系统调用接口只调用了一次。 这是什么原因从这个现象中能过得到什么呢 这个现象肯定是和缓冲区有关。缓冲区必然不在操作系统内核中。 既然缓冲区不在操作系统内核中也就是不是由操作系统来维护的那么它只能有进程去维护也就是编程语言本身来维护。 拿C语言来说和文件相关的操作FILE*类型的指针是至关重要的我们已经知道FILE是一个结构体它里面有文件描述符fd在结构体中定义的变量名是_fileno。 所以我们大胆猜测所谓缓冲区就在FILE这个结构体中。 来大概看看Linux的源码 在源码中和文件有关的结构体中有很多的指针变量如上图中红色框所示这些指针就是在维护缓冲区。 此时我们就可以知道缓冲区是由要打卡文件的进程申请的也是由这个进程来维护的缓冲区存在于FILE结构体中。 缓冲区的刷新策略 光知道缓冲区存在于FILE结构体中还不足以回答上面那个现象提出的问题接着本喵再介绍一下缓冲区的刷新策略。 同样上面的代码但是没有进行输出重定向而是直接打印虽然有fork但是仍然是各个接口只调用了一次。 将上面代码中字符串的换行符去掉不进行重定向直接打印发现C接口也被调用了两次。 这是什么原因从这个现象中又可以看出什么呢 缓冲区如果及时刷新那么各个接口只调用一次。缓冲区的刷新和换行符\n有关。 这种缓冲区的刷新和换行符\n相关的策略叫做行缓冲。 再看同样的代码都是有换行符的进行输出重定向以后C接口就调用了两次没有进行重定向C接口就只调用了一次。 这又是为什么从这个现象中可以看出什么 输出重定向后输出终端变成了文件没有重定时输出终端是显示器。行缓冲的策略在文件和显示器上作用效果不同。 文件采用的是全缓冲的方式只有当缓冲区满了以后操作系统才会刷新缓存区。 在程序中在C语言的打印函数接口调用完之后使用了fflush将缓冲区立刻刷新然后进行输出重定向到log.txt文件中此时C语言接口也是只打印了一次。 进行了重定向又仅打印了一次和上面进行重定向后只打印一次的结果完全不同。 这是为什么从这个现象中又可以看出什么 fflush进行缓冲区的刷新。没有遵循行缓冲或者全缓冲的策略。 这种使用fflush进行刷新缓冲区的刷新策略叫做**误缓冲。**它是由用户控制的直接将缓冲区中的全部内容都刷新都对应的终端上去。 还有两种情况下缓冲区同样也会刷新其一就是当一个进程结束后操作系统会自动将属于该进程的缓冲区进行刷新并且将对应的内存空间释放。 其二就是当一个文件被关闭的时候操作系统也会自动将属于该进程的缓冲区进行刷新。 来总结一下缓冲区的刷新策略 体现策略适用范围立即刷新无缓冲通常由用户控制进行强制刷新行刷新行缓冲显示器满了刷新全缓冲磁盘文件进行结束后刷新所有进程文件关闭时所有文件 不同的缓冲策略是根据一定的情况定死的我们一般情况下是不会进程重新定义的。 显示器直接给用户看的一方面要照顾到效率另一方面要考虑到用户是一行一行看文本的所以次用行缓冲策略。磁盘文件用户不需要立马看见文件中的内容为了效率采用全缓冲的方式。 缓冲区刷新一次是很耗费时间的比如1000个字节的数据刷新一次是1000个刷新十次也是1000个但是十次使用的时间会必一次长的多的多。 在进行缓冲区刷新的时候数据量的大小不是主要矛盾和外设预备IO的过程才是最耗费时间的。 解答疑惑 此时这个现象就可以解答了。 只有C接口被调用的次数发生了变化系统调用一直都是只调用一次说明系统调用不存在缓冲区。 父进程创建以后在调用C接口时将数据写到了它的缓冲区中并且通过页表在内存中映射了一段物理空间。在执行到return 0 之前的fork时创建了子进程子进程会拷贝父进程缓冲区中的全部内容并且通过页表映射到相同的物理空间。在fork之后父子两个进程什么都没有干进程将结束了在进程结束的时候会刷新它们各自缓冲区中的数据到磁盘文件中。因为有两个进程要结束所以缓冲区就会刷新两次而且内容是一样的。然后释放这块物理空间由于父子进程都没有对各自的缓冲区进行修改所以没有发生写时拷贝。 在没有重定向到程序中打印终端是显示器采用的是行缓冲的方式每个C接口打印的字符串中都有换行符所以每次调用完C接口后都会刷新缓存区中的内容。 在fork之后父子两个进程各自的缓冲区中什么都没有都已经被刷新走了所以它们两在结束的时候也不会再次刷新缓冲区所以表现出来C接口各自打印一次。 简单模拟用户缓冲区 为了能够对缓冲区有更深的了解下面本喵带大家简单的模拟实现一下用户缓冲区。 首先需要简历FILE结构体根据我们学习到的内容有文件描述符fd缓冲区。 同样需要一个刷新策略标志用32位中的3个比特来表示无缓冲行缓冲全缓冲。 这里仅仅是模拟一个缓冲区实际的缓冲区肯定不是一个数组。 打开文件函数 对于不同的打开方式给打开标志flags不同比特位赋值如上图中代码。 只读方式打开的话调用只有两个参数的系统调用open其他以写方式打开时调用有三个参数的open。从这里也可以看出无论上层语言是什么打开文件时最终都会调用系统调用open函数。 将文件成功打开以后对我们自定义的my_FILE结构体初始化。 结构体中的刷新方式默认采用行缓冲方式。将使用系统调用open返回的文件描述符fd赋值给结构体中的fd。将缓冲区(数组)进行初始化。 最后返回动态开辟的my_FILE指针。 写入函数 无论写入到内容是什么都要放在my_FILE结构体中的缓冲区中。 这里使用了memcpy函数从这里可以看出使用write系统调用后与其认为将数据写入到了文件中不如认为是将数据复制到了文件中。与其认为write是一个写入函数不如认为它是一个复制函数。 根据设定的不同刷新策略将my_FILE结构体中缓冲区里的数据通过系统调用write写到Linux内核中也就是写到文件中。 缓冲区刷新函数 如果缓冲区中有数据调用该函数时立刻将缓冲区中的数据写到Linux内核中。再将内核中的数据写入到文件中。 这里调用了一个fsync函数该函数的作用就将内核缓冲区中的数据刷新到文件描述符fd所执行的文件中。 我们使用系统调用write时其实是将数据写入到了内核缓冲区中而不是直接写入到了文件中。操作系统会将内核缓冲区中的数据再写入到文件中。 这里使用该函数来强制刷新内核缓冲区中的数据而没有让操作系统自主去刷新数据是为了防止内核缓冲区中的数据还没有刷新出去的时候系统就宕机了此时会导致数据的丢失。 至于操作系统是如何将内核缓冲区中的数据刷新到文件中的这是操作系统的事情了我们不需要再了解我们要掌握的是用户层语言所维护的缓冲区。 文件关闭函数 在关闭文件时将缓冲区中的数据刷新到内核中然后再通过系统调用关闭文件描述符所指向的文件。最后再释放my_FILE结构体以防造成内存泄露。 验证 可以看到使用我们自己模拟的fwrite函数可以实现和C接口一样的功能。 同样也可以实现追加。 ☕理解文件系统 在前面我们一直学习到都是被打开的文件和进程间的关系。事实上除了被打开的文件还有需要没有被打开的文件这些没有被打开的文件它们放在哪里呢又是如何被管理的呢 没有被打开的文件都静静的在磁盘上放着。磁盘上有大量的文件都被管理着方便我们随时打开。 要想了解文件时如何被管理的就需要对磁盘有一定的认识。 认识磁盘 物理结构 磁盘属于外设是一个机械结构所以相对CPU内存而言它相当的慢。 来看它的物理结构如上图所示之所以叫做磁盘是因为它是盘状的而且不止一片有很多片叠放在一起。 主轴和马达电机在主轴上套着多张盘片它们和轴相固定通过马达电机来驱动这些盘片一起转动。磁头每一张盘片都有两个盘面每一个盘面上都有一个磁头该磁头是用来向磁盘中读写数据的。多个磁头也是叠放在一起的它们的运动是一致的。音圈马达该马达驱动磁头组进行摆动它可以从盘片的内圈滑到外圈再结合盘片自身的转动从而向磁盘读写数据。 存储结构 磁头向磁盘中读写数据如上图中有三个盘片那么就有六个磁头给它编号从0到5。柱面从俯视图中来看一个盘面可以看做是多个同心圆每一个同心圆被叫做一个磁道一叠盘片中的相同磁道所组成的圆柱就这里的柱面从内到外给柱面编号从0到3。扇区在俯视图中以相同圆心角将盘片分为多个扇形每个扇形和每个磁道相交产生的区域就被叫做扇区。一个盘面上每个磁道所包含的扇区个数是相同的同样给每个扇区编号。 每个扇区的大小是512K字节所以内磁道的扇区密度高外磁道的扇区密度低。 这样一来我们就可以定位任意一个扇区然后进行读写数据。比如0号磁头0号柱面0号扇区此时磁头就会摆动到0号柱面处当0号磁头对应的盘面中的0号磁道里的0号扇区旋转到磁头位置时就可以向磁盘中读写数据。 这种定位方法称为CHS定位法。 逻辑结构 每个磁面上都有多个磁道每个磁道上有多个扇区类比磁带扇区就可以看成一圈一圈缠绕在一起的。 将缠绕在一起的扇区像拉磁带一样全部拉出来拉成一条直线。多个磁面可以拉成多个直线将所有面拉成的直线首尾相连组成一条长直线。这条长直线可以看成一个数组这个数组是以扇区为单位的所以每个数组元素的大小是512K。 此时磁盘就被我们抽象成了上图所示的数组并且给每一个扇区进行编号。站在操作系统的角度操作系统访问这个数组就是在访问磁盘。 那么这个数组的下标是怎么和磁盘的CHS对应起来的呢 如上图所示可以根据给定的逻辑数组下标转换成CHS定位法定位到磁盘上具体的某个扇区。 其中数组的下标被叫做逻辑块地址简称LBA。操作系统使用的就是逻辑块地址来访问磁盘的。 采用LBA而不用CHS的原因 便于管理因为数组管理起来更加方便。不想让操作系统的代码和硬件强耦合。 文件管理 操作系统看到的磁盘就是一个数组这个数组每个元素的大小是512K字节(一个扇区)同样我们也知道每次向磁盘中读写数据都很耗费时间。 为了提高效率磁头每次访问磁盘的基本单位是4KB(绝大多数情况下)。即使访问磁盘的一个bit磁头也是将包过这一个bit在内的周围4KB大小的数据加载到内存。 正因为磁头每次访问的是4KB大小的数据块所以内存也被划分成了多个4KB大小的空间每一个空间被叫做页框。 同样的磁盘中的文件尤其是可执行文件也被划分成了多个4KB大小的数据块每一个块被叫做页帧。 假设现在有一个500GB大小的磁盘操作系统如果统一管理的话成本会很高所以采用分治的思想来管理整个磁盘。 将500GB的磁盘分成4个区只需要管理好一个区其他三个区便可以复用这套方法。 再将每个区分为多个组只需要管理好一个组其他剩下的组便可以复用这套方法从而管理好这个区。 每个分区以及每个分组是多大要看具体情况。 这种思想有点像递归的思想所以我们要学习到重点就是如何管理好一个组。 最小分组的管理 每个分组中又分为这6个区域。 Super Block文件系统的属性信息整个分区属性的属性集多个组都有 但不一定是每个组都有。是为了防止磁盘被刮伤而找不到文件属性。inode Table存放了这个分组中所有的inode(已经使用的和没有使用的)每个分组中inode的个数是确定的。inode Bitmapinode位图该分组中有多少个inode这个位图就有多少个bit并且每一个比特位都与一个inode一一对应。每使用一个inode对应的位图就会被置1。Data blocks保存这该分组内所有文件的内容该块区又被分为多个数据块。Block Bitmap数据块位图该分组的Data blocks中有多少个数据块这个位图就有多少个bit并且每一个比特位都和一个数据块一一对应。每使用一个数据块对应的位图就会被置1。GDT描述表记录该分组中inode和数据块的使用率等宏观属性。 这样来看肯定是一头雾水下面本喵继续来解释。 文件 属性 内容所以在磁盘上管理一个文件也要管理它的属性和内容而文件的属性就放在一个叫inode的结构体中文件的内容就放在数据块中。 文件属性存储 struct inode {int id;mode_t mode;size;.......//多种属性int blocks[15]; }一个文件的所有属性都在inode中但是唯独没有文件名。 查找一个文件的时候统一使用的是inode编号。 可以看到每个文件都有一个独一无二的编号这就是inode编号这个编号其实就是一个结构体对象。 每创建一个文件就会在inode Table中申请一个未被使用的inode并且将对应的位图置1。 每一个inode的大小都是128B并且每个分组中inode的个数都是固定的。 文件内容存储 文件的内存就存储在这个Data blocks中而这个块区中又有多个数据块并且有相应的编号。 现在属性被存放好了内容也被存放好了下面就是将一个文件的属性和内容对应起来。 inode结构体中的数字blocks[15]就是干这个事情的。 数组中每个元素存放着一个一个数据块的block id(编号)。 每个数据块中存放着内容数据。 一个文件对应着一个ionde该文件的内容存放在多个数据块中所以inode中的数组中记录着这些数据块的block id。 这个数组一共才能放15个编号如果这个文件的内容有很多呢需要很多的数据块(超出了15个)呢 数组最后的三个位置下标为12,13,14它们存放的数据块编号所指向的数据块中存放的不是文件内容同样是属于该文件数据块的编号。 虽然一个数组中的一个元素只能存放一个数据块的下标但是指向的数据块中可以存放多个数据块的下标这样一来再大的文件也能存放的下。 每使用一个数据块就会将它所对应的位图置1。 现在我们知道了文件在磁盘上是如何存放的以及操作系统是如何管理它们的。根据前面所讲inode是文件的唯一标识但是我们在使用文件的时候并没有使用inode啊我们使用的是文件名这是为什么 一个目录中可以包含多个文件但是这些文件的名字不能重。目录也是文件它也有自己的inode也有自己的数据块。 目录的data blocks中存放的是它所包含文件的文件名和inode之间的映射关系。 所以我们在使用一个文件的文件名时就会自动映射到它的inode本质上还是在使用一个文件的inode。 此时我们就清楚了为什么inode中包含文件的所有属性但是就是没有文件名了因为文件的文件名和它对应的inode存在上级目录的data blocks中。 操作未被打开文件 创建文件 在创建文件的时候会向inode Table中申请为被使用的inode并且将相应的inode Bitmap置1然后将该文件的各种属性存入到inode中。还会将这个文件的文件名和inode的映射关系写入到上级目录的data blocks中。 向文件中写入 根据文件名和inode的映射关系找到文件对应的inode。根据inode中blocks数组找到存放文件内容的数据块进行数据的写入如果发生数据块数量上的变化还要将对应的Blocks Bitmap位图的相应位改变。再改变inode中对应的属性信息。 读取文件内容 根据文件名和inode的映射关系找到文件对应的inode。再从inode中找到文件对应的数据块。将数据块中内容加载到内存中供进程使用。 文件删除 根据文件名和inode的映射关系找到文件对应的inode。再根据inode找到数据块所对应的Blocks Bitmap将对应位清0。最后再将inode对应的inode Bitmap清0。 文件的删除并不会去清理磁盘上数据块中的内容只是将对应的位图清0后续再来的内容进行覆盖就可以。这也是为什么拷贝一个文件比较慢但是删除一个文件很快的原因。 当你误删一个文件的时候最好的做法就是什么都不要做只要对应的inode和data blocks没有被覆盖这个文件时可以恢复的。 如此一来磁盘的一个分组就能被操作系统井井有条的管理好了这也意味着整个磁盘也就被管理好了。 ☕总结 在平时我们看不见摸不着的缓冲区此时便揭下了它神秘的面纱它的位置刷新策略以及因为它而导致的种种异常现象此时便都明白了。虽然文件系统的讲解更多的是理论但是这对于我们更好的理解文件系统有很大的帮助尤其是每个分组中的那个六个区域至关重要。
http://www.dnsts.com.cn/news/182364.html

相关文章:

  • 网站做支付需要准备什么建设银行短信开通网站
  • 马鞍山网站建设公司月子会所网站建设方案
  • 万网个人网站备案查询小说网站怎么做不违法
  • 广告行业包括网站建设吗网站上怎么做动画广告
  • 松江泗泾网站建设青岛网站建设哪家好 网络服务
  • 做网站电信运营许可证公司网站二维码生成器
  • php网站开发难吗网络营销策划书1500字
  • 阿里云做网站可以吗珠海微网站进入
  • 广州萝岗区网站建设网站后台用户名不存在
  • 网站建设主要包括哪两个方面新东方烹饪学校
  • 江苏省工程建设标准定额网站seo外链怎么做能看到效果
  • 平面设计有什么网站wordpress点击文字弹出层
  • 北京网站建设流程搭建网站服务器
  • 网站跳转如何做某某公司网站建设论文
  • 关于配色的网站推荐衡阳高端网站建设
  • 局域网网站wordpress模板中文版
  • 青海建设厅官方网站交互设计师工资一般多少
  • c网站制作商城网站的运营
  • 彩票网站开发是否合法网站保持排名
  • 网站建设优化seo修改wordpress后台文字
  • cdr做网站唐山的网站建设公司
  • 网站建设的软件平台合肥网站空间
  • 网站 防采集辽宁定制网站建设推广
  • 什么网站做家具出口wordpress怎么改图片
  • 菜鸟怎样做自己的网站wordpress获取指定分类的图像描述
  • 帮公司做网站怎么找购买建立网站费怎么做会计凭证
  • 分销网站建立上海网络推广联盟
  • 免费发帖推广网站建设银行网站怎么先无贷款呢
  • 怎么设计一个自己的网站贡井网站建设
  • 营销型企业网站建设应遵循的原则wordpress 模板制作教程