Linux基础I/O之文件缓冲区

news2025/1/11 21:54:02

一、缓冲区的基本概念

       缓冲区这个概念,我相信大家或多或少的有听到过,那么其到底是个什么东西呢? 简单地理解一下,其可以被看做一部分的内存(可以认为是malloc来的)。

        那为什么要有缓冲区这个东西呢?其有什么作用呢?先说结论,缓冲区的主要作用就是来提高我们的效率(提高使用者的效率,提高发送效率)。那其是如何做到提高效率的呢?这里我给大家举个例子:
        比如说发快递,通常我们寄快递都会送到菜鸟驿站,但是其不会立刻将我们的快递发送出去而是会积累一部分快递,等到一定程度再进行发送。由此我们可知,因为由(驿站)缓冲区的存在,我们可以积累一部分的数据在统一进行发送。而根据我们的冯诺依曼体系结构可知,我们的内存跟硬件设备的交互是很慢的,为了避免过多的交互操作,于是就有了缓冲区的概念,先将内容写入到缓冲区中,等到一定规模之后,再统一的写入到硬件资源中,这就可以提高我们OS的效率。

        缓冲区因为能够暂存数据,必定要有一定的刷新方式,因为其到时需要向硬件写入资源:

  1. 无缓冲(立即刷新):每次写入数据都会立即被写入目标,无任何缓冲。适用于对实时性要求高的场景,例如标准错误输出。

  2. 行缓冲(行刷新):每当遇到换行符时,缓冲区中的数据会被刷新到目标。这种模式适用于文本文件或控制台输出,使输出操作更高效,但每行的结束会触发刷新。

  3. 全缓冲(缓冲区满了再刷新):数据在缓冲区中积累到一定量后才会写入目标。这种模式适用于文件写入等操作,可以减少写入次数,提高性能,但在缓冲区未满时数据不会立即显示。这些模式可以根据具体需求来调整,以平衡性能和实时性。

  4. 也可以自定义刷新策略

以上是一般策略,存在特殊情况:1.强制刷新  2.进程退出的时候,一般都会进行刷新缓冲区

二、样例展示

        说了这么多我们写一段代码来看看吧,虽然不能直接看到缓冲区,但是可以帮助我们加深对其的理解。

首先我们来对这一段代码解析一下,printf我们很熟悉了,就是向显示器进行打印,fprintf向stdout进行打印,也就是显示器,fputs也是如此,write在上篇文章已经给大家说过了,这里就不过多赘述了,接下来我们看看结果。


这里输出没什么特别的,接下来我们来改改代码。

这里对我们的输出做一个重定向的工作,同时在代码的最后我们fork()一下。可能有人会说了,欸这有什么区别吗,无非就是刚刚的输出被冲定向到了文件中而已,那么接下来让我们看看结果吧。

先说现象,原先的输出都有内容也没变,但是呢,次数变多了,且还有一件奇怪的事情,唯独write写入的那份没变多,这是为什么呢?且看下文。

三、样例分析

在上文我有说过缓冲区的刷新方式,这里补充一点小细节,同时对案例进行分析。

  1. 当我们直接向显示器打印的时候,显示器文件的刷新方式是行刷新!而且你的代码输出的所有字符串,在\n,fork()之前,数据全部已经被刷新,包括systemcall。
  2. 而当重定向到test.txt,本质是向磁盘文件中写入(不是显示了哦),我们系统对于数据的刷新方式已经由行刷新变成了全缓冲。 
  3. 全缓冲意味着缓冲区变大,实际写入的简单数据,不足以把缓冲区写满,fork执行的时候,数据依旧在缓冲区中!
  4. 在这里我们所谈的"缓冲区",和操作系统是没有关系的 ,只能和C语言有关。也就是说,这里我们所谈的主要是语言级别的缓冲区(用户级缓冲区)。
  5. C/C++提供的缓冲区,里面一定保存的是用户的数据,属于当前进程在运行时自己的数据。 如果我们把数据交给了OS,这个数据就属于OS,不属于当前进程了。
  6. 当进程退出的时候,一般要进行刷新缓冲区,即便你的数据没有满足刷新条件 --- 这个行为属于清空或者"写入操作" --- 我们知道任意一个进程在退出的时候,要刷新缓冲区,就要发生写时拷贝,所以fork()虽然并没有调用前面我们所说的函数,但其和父进程指向统一块缓冲区,退出发生写时拷贝,所以就有两份结果。
  7. 而我们的write是系统调用,也就是说write没有使用C的缓冲区,其数据会直接写入到到操作系统中!不属于进程了,就不会发生写时拷贝。
  8. 其实我们的文件也是需要有缓冲区的,这是内核级别的缓冲区,我们的write系统调用可以理解为直接向文件缓冲区进行写入。这里我们重新再理解一下刷新,从C缓冲区写入OS(文件缓冲区)这个工作叫做刷新。

       谈了这么久的缓冲区,我们要怎么去看看这个缓冲区到底在哪呢?任何情况下,我们输入输出的时候,都要由一个FILE,FILE是一个结构体,FILE里面包含了fd,同时包含一个缓冲区。这里大家可以去看看源码,加深加深自己的理解。最后用一张图总结一下这些知识。

       

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

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

相关文章

C语言典型例题48

《C程序设计教程(第四版)——谭浩强》 习题3.8 有4个圆塔,圆形分别为(2,2)、(-2,2)、(-2,-2)、(2,-2),圆半径为…

uni-app 手记集。

1、uni-app 是一个使用 Vue.js 开发的前端应用的框架&#xff0c;所以不会Vue.js的小伙伴可以先去看看Vue.js的基础教学。 2、.vue文件结构 <template><div class"container"></div> </template><script type"text/ecmascript-6&q…

开放式耳机怎么戴?会有伤害?四款开放式蓝牙耳机排行榜前十名

老实说&#xff0c;开放式耳机对耳朵会产生什么伤害&#xff1f;我不太能想出来。我倒是觉得入耳式耳机可能会&#xff0c;因为入耳式耳机需将耳机塞入耳朵耳道&#xff0c;那就会对耳道产生影响。使用者在佩戴入耳式耳机的时候耳道会变成一个接近完全封闭的状态&#xff0c;耳…

【实战篇】Port配置

目录 1 前言1.1 开发板特性1.2 电路原理分析2 步骤2.1 General配置2.2 PortContainer配置3 总结1 前言 本文讲解如何配置Port模块。Port的引脚配置在整个实验中非常的重要,一旦配置错误可能会导致实验失败。引脚如何配置,完全依赖于我们的硬件设计和芯片型号,我们这里以英飞…

PE文件空白区添加代码

1、C源码 #include <iostream> #include<windows.h>int main() {int i 1;std::cin >> i;if (i 100){MessageBoxA(0, 0, 0, 0);}return 0; }2、将上述源码编译成可执行文件PEParase.exe&#xff0c;备用 3、使用010Editor打开该exe文件&#xff0c;查找PE…

git revert操作引起的代码丢失以及解决方案

场景如下&#xff1a; 某项目下有很多开发中的分支&#xff0c;比如分支a&#xff0c;b&#xff0c;c&#xff0c;d都合并到了一个test分支上&#xff1b;某次误操作将test分支内容合到了分支e上&#xff0c;然后紧接着又revert了这次合并&#xff0c;试图撤销合并&#xff1b…

如何解决Windows虚拟机不能安装vmtools的问题?

今天学到个小tips给大家分享一下&#xff01;&#xff01;&#xff01;解决win7安装不了vmtools的问题&#xff0c;以及如何打补丁&#xff01; 大家有没有遇到过下面的问题&#xff0c;就是在再给win7装vmtools的时候无法安装的情况&#xff0c;我这里这个是win7的旗舰版就遇…

Google Ads投放 | 如何分析竞争对手的谷歌广告?

Google Ads广告投放是出海企业的必重要营销动作之一&#xff0c;而分析竞争对手的 Google 广告是优化您自己的广告策略的关键步骤。通过了解竞争对手的动向&#xff0c;您可以发现改进的机会并在竞争中保持领先地位。 今天整理了Google Ads 竞争对手分析的4种方法&#xff1a; …

Linux基础知识学习(五)

1. 用户组管理 每个用户都有一个用户组&#xff0c;系统可以对一个用户组中的所有用户进行集中管理&#xff08;开发、测试、运维、root&#xff09;。不同Linux 系统对用户组的规定有所不同&#xff0c;如Linux下的用户属于与它同名的用户组&#xff0c;这个用户组在创建用户…

技术速递|将 .NET Aspire 添加到您现有的 .NET 应用程序中

作者&#xff1a;Jon Galloway 排版&#xff1a;Alan Wang .NET Aspire 是一个针对 .NET 的新型云就绪堆栈&#xff0c;可帮助开发人员快速轻松地开发分布式应用程序。您可能已经看过一些演示&#xff0c;展示了大型 .NET 解决方案&#xff0c;其中充满了复杂的云依赖项&#x…

租房网站

TOC springboot0762租房网站 JAVA简介 Java主要采用CORBA技术和安全模型&#xff0c;可以在互联网应用的数据保护。它还提供了对EJB&#xff08;Enterprise JavaBeans&#xff09;的全面支持&#xff0c;java servlet API&#xff0c;Java&#xff08;java server pages&…

在家上班,躺着收钱?分享远程工作程序员的真实生活……

这是《开发者说》的第15期&#xff0c;与以往采访的活跃于各行各业的开发者不同&#xff0c;这次我们将目光投向了优秀的远程开发者&#xff0c;本栏目将分享自由远程工作者的经历、见解和故事&#xff0c;希望能给大家带来一些崭新的视角。 这次我们邀请到的是拥有10年开发经…

秃姐学AI系列之:AlexNet + 代码实现

目录 深度学习之前的网络 机器学习 几何学 特征工程 总结 深度卷积神经网络的突破的两个关键因素 数据 ImageNet&#xff08;2010&#xff09; 硬件 90年&#xff1a;数据量和计算能力发展的均匀且都不大的时候——神经网络 00年&#xff1a;内存不错、算力也不错&a…

秃姐学AI系列之:使用块的网络——VGG

目录 VGG VGG块 VGG架构 总结 模型演变进度 代码实现 QA VGG 上文讲的 AlexNet 虽然证明了深层神经网络卓有成效&#xff0c;但它没有提供一个通用的模板来指导后续的研究人员设计新的网络。 与芯片设计中工程师从放置晶体管到逻辑元件再到逻辑块的过程类似&#xff0c…

AI大模型独角兽 MiniMax 基于 Apache Doris 升级日志系统,PB 数据秒级查询响应

作者&#xff1a;MiniMax 基础架构研发工程师 Koyomi、香克斯、Tinker 导读&#xff1a;早期 MiniMax 基于 Grafana Loki 构建了日志系统&#xff0c;在资源消耗、写入性能及系统稳定性上都面临巨大的挑战。为此 MiniMax 开始寻找全新的日志系统方案&#xff0c;并基于 Apache …

基于Crontab调度,实现Linux下的定时任务执行。

文章目录 引言I 预备知识Crontab的基本组成Crontab的配置文件格式Crontab的配置文件Crontab不可引用环境变量杀死进程命令II Crontab实践案例Crontab工具的使用重启tomcat服务每分钟都打印当前时间到一个文件中30s执行一次III 常见问题并发冗余执行任务&& 和|| 和 ;的区…

ChatGPT 的幻觉有改善吗?

​​​ 在早在 ChatGPT 刚刚问世时&#xff08;几个月前&#xff09;&#xff0c;我就曾写过一篇文章&#xff0c;描述它愿意&#xff08;不&#xff0c;是渴望&#xff09;向用户提供大量虚假信息。这些错误被称为幻觉&#xff0c;这是一个技术术语&#xff0c;强调了 ChatGPT…

安装docker+docker远程连接

docker Docker 是⼀个开源的应⽤容器引擎&#xff0c;可以实现虚拟化&#xff0c;完全采⽤“沙盒”机制&#xff0c;容器之间不会存在任何接⼝。 docker架构 docker核心概念 1. 镜像&#xff08;images&#xff09;&#xff1a;⼀个⾯向 docker 容器引擎的只读模板&#xff0c;…

89.SAP ABAP数据类型 - 笔记

1.SAP ABAP数据类型 目录 全局类型 标准类型 局部类型 全局类型 数据字典中创建的类型&#xff08;下图中②&#xff09; Data Element 是一个数据的类型&#xff0c;包含了这个元素的寓意属性&#xff0c;它包含了一些非结构化的数据对象的技术属性&#xff08;域&#…

丈夫每次回家打妻子,还在外染上性病,婚后没完整过一个年

丈夫每次回家打妻子&#xff0c;还在外染上性病&#xff0c;婚后没完整过一个年 这是一篇涉离婚纠纷的民事起诉状 &#xff08;范文点评&#xff09; 离 婚 起 诉 状 原告&#xff1a;徐某秀&#xff0c;女&#xff0c;现年48岁&#xff0c;汉族&#xff0c;无业&#xff0c…