做h5动画的素材网站,网络规划设计师培训视频教程,济南建设网建筑市场信用信息管理,如皋网站开发文章目录 缓冲区什么是缓冲区#xff1f;缓冲区的意义是什么#xff1f;缓冲区的刷新方式 理解缓冲区用户缓冲区和内核缓冲区缓冲区在哪里#xff1f; 本篇主要总结的是关于缓冲区的概念理解#xff0c;以及再次基础上对文件的常用接口进行一定程度的封装
缓冲区
什么是缓… 文章目录 缓冲区什么是缓冲区缓冲区的意义是什么缓冲区的刷新方式 理解缓冲区用户缓冲区和内核缓冲区缓冲区在哪里 本篇主要总结的是关于缓冲区的概念理解以及再次基础上对文件的常用接口进行一定程度的封装
缓冲区
什么是缓冲区
如何理解缓冲区简单来说缓冲区就是一段内存用来存放一些信息这就是对于缓冲区最初步的理解。那如何证明缓冲区的存在用下面的代码来验证缓冲区
#include stdio.h
#include unistd.hvoid buffertest()
{printf(hello linux);sleep(3);
}int main()
{buffertest();return 0;
}现象
运行结果如上所示会先休眠三秒再输出结果按程序的顺序结构来说sleep一定是在printf之后执行的也就意味着当执行到sleep的时候运行结果已经被写到了某个地方只是还没有刷新到显示器上因此用户看不见显示的内容而当sleep执行完毕后此时会把内容刷新到显示器上这样就能看到运行的结果了
解释
而在执行了printf函数后其实就已经把内容输出了输出的地方其实就是缓冲区中只是还没有将信息存储到显示器这个文件内因此没有输出结果而当进程结束后就会把缓冲区中的信息都刷新到显示器中此时就实现了把信息打印到显示器上所以才会看到程序运行后没有输出结果而是在执行完sleep后才会输出到显示器上
缓冲区的意义是什么
如何理解缓冲区有了这个缓冲区能干什么呢答案是提高效率对于这个答案其实并不陌生在前面的学习中也存在有关于缓冲区的概念只是对于缓冲区的认知程度比较低
举个例子来说现在用户在上层使用C语言打印了很多信息但是没有发出要刷新的需求那么此时这些信息就都会存储在缓冲区中而当缓冲区满了或者触发其他的刷新策略的时候就会统一把缓冲区中的信息转移到内存中再由内存进行其他后续的操作在本文的后面会对这一整体的操作进行分析此处只进行初步的描述
从外部把信息存储到内存中是需要成本的而缓冲区的存在就是把这些信息积攒到一定程度再进行发送既然设计出缓冲区的存在那么就意味着把信息从缓冲区发送到内存中比直接把信息发送到内存中需要付出的成本低这样可以提高运输的效率
缓冲区的刷新方式
缓冲区可以暂存数据就意味着一定会有对应的刷新方式
无缓冲(立即刷新)行缓冲(行刷新)全缓冲(缓冲区满了才刷新)
一般而言是可以使用上面的刷新策略的但是在实际的进程运行过程中可能会出现其他的意外情况例如
强制刷新进程退出了一般会刷新缓冲区
一般而言对于显示器文件会采用的是行刷新策略而对于磁盘上的文件会采用全缓冲的策略对于这两种不同的刷新策略下一个模块就进行分析
理解缓冲区
下面来看这样的测试代码样例
void buffertest2()
{fprintf(stdout, C:hello fprintf\n);printf(C:hello printf\n);fputs(C:hello fputs\n, stdout);const char* str system call: hello write\n;write(1, str, strlen(str));fork();
}运行结果 将运行结果输出到另外一个文件中 此时会发现有异常现象出现了对于C语言的接口会打印输出两套而对于系统调用的接口只会输出一套那么这是为什么呢为什么要在代码中进行fork的操作呢fork的操作会带来怎样的影响这两种现象出现的原因是什么呢
对于上述现象的理解和解释
首先对于上面的异常现象要从出现异常的操作出发为什么会出现异常原因是一个是将内容直接执行运行到显示器上一个是把执行的结果输出到一个文件中那么这两个操作会带来区别吗答案是一定会的原因就是前面提到的刷新方式的变换对于显示器来说是行刷新策略对于磁盘来说是全刷新策略那么这就会带来不一样的结果具体的原因后续分析全缓冲意味着缓冲区会变大实际写入的简单数据不会把缓冲区写满因此在执行fork操作的时候数据依旧在缓冲区中没有被刷新到文件中在上述的代码中所使用到的缓冲区全部都是C语言的缓冲区这个缓冲区是C语言本身给我们提供的因此和操作系统内部提供的缓冲区是两种缓冲区没有关系那么问题来了这和fork有什么关系呢fork会带来什么结果呢那么现在就要思考的是fork会带来什么结果根据前面的思想不难想到fork带来的第一个直观的效果就是创建一个子进程这是不需要质疑的事而对于这个进程来说fork结束后带来的另外一个结果就是结束进程而结束进程带来的结果就是会刷新缓冲区既然刷新缓冲区了那么就会把这个进程所对应的缓冲区内容清空那么下一个问题就是关于写时拷贝的问题缓冲区清空算不算进程的数据发生改变了呢如果算发生改变就会发生写时拷贝如果不算改变就不会那么下一个问题就是进程的数据在清空缓冲区的时候算不算发生了修改要解决上面的这个问题本质上是思考C语言的缓冲区中的数据算不算进程运行时候的数据因为写时拷贝的触发原理就是进程运行时候父进程和子进程中只要有一个进程中的数据被修改就会给另外一个进程发生写时拷贝而这里的缓冲区的数据一定是属于进程运行时的数据的而与此同时需要注意的是当把数据已经交给操作系统之后此时数据就是操作系统的而不是进程本身的数据了对于这样的数据即使发生修改也并不隶属于写时拷贝的范畴那么分析到这里其实对于上面的这个现象已经理解的很到位了现在还有最后一个问题为什么这个进程中对于使用系统调用的数据没有发生写时拷贝难道这个不算是C语言缓冲区的数据以至于这个数据不算进程的数据就不会发生写时拷贝吗答案是肯定的这是因为缓冲区也有很多类而除了系统调用外的其他写入的方式都是使用的是C语言自身所提供的一个缓冲区因此在这样的基础下进行的数据是属于进程的数据的而使用系统调用的接口使用的数据其实并不属于它没有使用C语言缓冲区
总结
经过上面的这几条分析其实已经把缓冲区的概念总结的算是比较到位了刷新其实就是把C缓冲区的数据写入操作系统
用户缓冲区和内核缓冲区
什么是用户缓冲区什么是内核缓冲区
用户缓冲区
用户缓冲区其实就是平时日常的使用中提供的语言级别的缓冲区在用户层面把信息进行写入这样的级别就是用户缓冲区所做的事作为用户上层进行了一系列的各种写入这些操作都是在给用户缓冲区中写入信息而从用户缓冲区再向着操作系统写入信息这个过程就是刷新经过刷新就可以把信息写入操作系统而在操作系统内部又会有一套完整的文件系统关于文件系统在上一篇文章中已经完整的描述过内部的过程这里就不再详细叙述了
内核缓冲区
既然将内容从C语言写到操作系统中需要缓冲区那么把读取的信息刷新到磁盘中是不是也是需要缓冲区的介入呢答案是肯定的这是一定会有的而这其实也是刷新把内核缓冲区的数据写到磁盘中也是一种刷新只不过刷新策略和前面的C缓冲区不太一样而已这里就对内核缓冲区不再进行过多的介绍了它本质和硬件设备相关更多一些
缓冲区在哪里
那这个缓冲区在哪里呢其实也是可以找到的调用指令进行搜索
whereis stdio.h打开文件寻找FILE有关的内容 那么下一步就是寻找这个结构体究竟在哪里 在这个libio.h文件中寻找到了这个内容而在进行输入和输出的时候就会有一个FILE而FILE本质上就是一个结构体这个结构体叫FILE里面就包含了fd这个FILE结构体就会提供一段缓冲区