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

【Linux】基础IO_缓冲区

hello~ 很高兴见到大家! 这次带来的是Linux系统中关于基础 IO这部分的一些知识点,如果对你有所帮助的话,可否留下你宝贵的三连呢?
个 人 主 页: 默|笙


文章目录

  • 一、理解缓冲区
    • 1.1 文件打开和读写的基本过程
    • 1.2 内核文件缓冲区
    • 1.3 语言级缓冲区
  • 二、缓冲区刷新问题
    • 2.1 语言缓冲区
    • 2.2 内核文件缓冲区

一、理解缓冲区

1.1 文件打开和读写的基本过程

  1. 我们知道,文件在没有打开之前是放在磁盘里面的,打开的过程就是将文件加载进入内存里面,毕竟cpu想要访问文件只能通过内存。
  2. 打开一个文件,进程首先调用open()系统调用,然后OS会创建一个描述该文件的结构体,它直接或间接包含了文件的所有属性。然后这个结构体会分配到一个该进程的文件描述符fd,方便进程对打开的文件进行管理。
  3. 文件等于属性+内容,对文件进行读写,就是对文件的内容进行读取或修改,但是cpu无法直接修改磁盘里面的文件,它得通过内核缓冲区来进行修改。

1.2 内核文件缓冲区

  1. OS首先会把文件的内容按需加载到内核缓冲区,然后将内核缓冲区的内容拷贝到用户缓冲区,再将cpu修改过后的用户缓冲区的内容拷贝到内核缓冲区,最后通过OS自动刷新到磁盘里面。从而完成对磁盘文件的读取和修改。

  2. 所以系统调用read和write接口的真正作用其实是拷贝,read是将内核缓冲区的内容拷贝到用户缓冲区,而write是将用户缓冲区的内容拷贝到内核文件缓冲区。

  3. OS将内容加载到缓冲区,就跟scanf从键盘读取数据一样,如果没有读取到就会阻塞在那里。一开始缓冲区里面什么都没有,那么OS就会根据调用的接口自动加载内容到缓冲区。

  4. 内核文件缓冲区在OS内核里面。

1.3 语言级缓冲区

  1. 如果我们每修改一次文件内容,都调用系统调用read和write对内容进行拷贝。那么它的效率将会很低。毕竟调用系统调用是有成本的,尤其对于read和write这种拷贝函数。比如我们用malloc、new申请空间都是有成本的,所以vector进行扩容都是2倍或1.5倍扩容而不是按需扩容,就是为了减少调用malloc/new函数的次数。
  2. 要提升效率,也就是要减少read和write的系统调用次数。那我们是否可以这样:将用户缓冲区里面的内容先放到一个地方给它存起来,不立刻拷贝到内核缓存区,而是等这部分存储的内容到达了一个指标之后再将它们一起打包拷贝到内核缓存区。这样就能够减少write的调用次数。这个用来存储数据的地方就是语言缓存区。减少read调用则与减少write调用相反,减少write是将先把小数据攒到用户缓冲区,达标后批量写;而减少read是将先批量读大块数据到用户缓冲区,再从缓冲区里按需取小数据。系统层面优化不了,所以优化就得放在语言层面了。
  3. 打一个比方就是:像我们寄快递,商家不会因为我们这一件快递就让快递车上路,那样效率既低费用也会提升。而是等个一两天,等快递数量到达一个指标之后将它们一起运送。

  1. 那么这个语言缓冲区它在哪里?我们知道FILE它是一个结构体,用fopen打开文件后会返回一个FILE类型的指针,stdout、stdin和stderr都是FILE类型。那么这个结构体它里面包含了哪些东西?首先一定是有文件描述符fd,这样才能够管理这个文件,而语言缓冲区也是在这个结构体里面的,语言缓冲区分为输出缓冲区和输入缓冲区。
  2. 像我们用fgets等c语言函数而非系统调用进行读取写入时,都是通过语言级缓冲区。
  3. 我们平常所说的缓冲区指的是语言级缓冲区,像之前我们接触到的系统接口_exit和接口exit。二者的区别就是_exit不会清空缓冲区,而exit会,这就说明语言级缓冲区是绝对不在OS里面的。
  4. fclose封装了系统调用close,close的作用是关闭fd,而fclose的作用是清空缓冲区,关闭fd,释放FILE指针。 它们都会切断语言级缓冲区和内核文件缓冲区之间的联系。
  5. 看如下代码:
7intmain()8{9close(1);10intfd=open("log.txt",O_WRONLY|O_CREAT|O_TRUNC,0666);11printf("fd is : %d\n",fd);// stdout -> 112fclose(stdout);13return0;14}

7intmain()8{9close(1);10intfd=open("log.txt",O_WRONLY|O_CREAT|O_TRUNC,0666);11printf("fd is : %d\n",fd);// stdout -> 112//fclose(stdout);13close(fd);14return0;15}

  1. 我们先关闭文件描述符1所对应的显示器文件,然后打开log.txt文件成为新的stdout所对应的文件。如果我们用fclose关闭文件,它会刷新缓存区,所以我们仍然能够在文件log.txt里面看到用printf输出的内容。而如果用close关闭文件,它就不会刷新缓冲区,而是直接切断缓冲区和内核文件缓冲区之间的联系,在文件log.txt里面我们就看不到printf所输出的内容,想要看到就必须刷新缓冲区,这里我们可以用fflush接口来刷新缓冲区。
7intmain()8{9close(1);10intfd=open("log.txt",O_WRONLY|O_CREAT|O_TRUNC,0666);11printf("fd is : %d\n",fd);// stdout -> 112//fclose(stdout);13fflush(stdout);14close(fd);15return0;16}

二、缓冲区刷新问题

2.1 语言缓冲区

  1. 什么时候要将语言缓冲区的内容拷贝到内核文件缓冲区(刷新)里面去?总体可以分为三种情况:
  1. 进程结束的时候,会自动刷新。
  2. 如果目标文件是显示器文件,刷新方式为行刷新。—>行缓冲
  3. 普通文件一般都是缓冲区写满了,才会进行刷新。---->全缓冲
  1. 我们来看一段代码:
10//c语言向显示器打印文件11printf("hello printf\n");12fprintf(stdout,"hello fprintf\n");13constchar*s="hello fputs\n";14fputs(s,stdout);1516//系统调用17constchar*ss="hello write\n";18write(1,ss,strlen(ss));192021fork();22return0;

  1. 我们仅仅是改变了目标文件,就会有这么大的差异。第一次我们执行的时候,它的目标文件是显示器文件,是行缓冲,只要有\n换行符就会刷新缓冲区。第二次我们更改目标文件,目标文件变成log.txt这个普通文件,缓冲方式就变成了全缓冲,用c语言库函数输出的内容会放到语言级缓冲区,直到进程结束才刷新到内核文件缓冲区,而系统调用write它是直接拷贝到内核文件缓冲区的,这就是为什么第二次write跑到前面去了的原因。至于第二次为什么库函数会有两遍,这是因为fork之后子进程继承了父进程的缓冲区,第一次没有是因为父进程缓冲区空空如也。

2.2 内核文件缓冲区

  1. 内核文件缓冲区的刷新方式取决于OS自主刷新,一般分为立即刷新和等OS不忙了之后再刷新进磁盘里面。
  2. 只要把数据从用户缓冲区拷贝到内核文件缓冲区,就相当于将数据交给了硬件,因为接下来的工作就是OS的了,我们没有办法干预。但是从客观上来讲,我们只是将数据交给了内核文件缓冲区而不是磁盘,什么时候交给磁盘全看OS,但如果有立即刷新到磁盘的需求,可以使用系统调用fsync()。


今天的分享就到此结束啦,如果对读者朋友们有所帮助的话,可否留下宝贵的三连呢~~
让我们共同努力, 一起走下去!

http://www.jsqmd.com/news/436546/

相关文章:

  • 2026主治医师考试资料红黑榜!在职医生高效提分不踩坑 - 品牌测评鉴赏家
  • 医学考研资料大揭秘:哪家才是你的上岸神器? - 品牌测评鉴赏家
  • 医学考研刷题软件哪家好?亲测10+款,避坑指南+宝藏推荐,医考党直接抄作业 - 品牌测评鉴赏家
  • 2026医学考研课程红榜|6大口碑机构深度测评,避开90%选课坑! - 品牌测评鉴赏家
  • 行业内靠谱的2025板材工厂排名 - 品牌推荐(官方)
  • 2026年知名的硼酸 品牌推荐:工业硼酸/切削液用硼酸实力工厂推荐 - 行业平台推荐
  • 医学生考研必备!这些刷题APP助你上岸 - 品牌测评鉴赏家
  • 在不确定中寻找可能性:重思“量子原住民”的教育哲学
  • 2026年热门的冷却塔清淤机器人 公司推荐:污水厂清淤机器人/水下智能清淤机器人/ZDLH-300R智能清淤机器人源头工厂推荐 - 行业平台推荐
  • Qt进阶:深入核心机制——揭开MOC(元对象编译器)的魔法
  • 靠谱的2025板材十大品牌推荐榜 - 品牌推荐(官方)
  • 使用 Certbot 自动生成/更新证书 + 同步到其他机器
  • Mybatis相关面试题
  • 实战指南|XSS攻击完整防御方案(前端+后端,零基础也能上手)
  • 2026年口碑好的家具拉手 工厂推荐:意法式家具拉手/高端定制家具拉手/衣柜橱柜家具拉手长期合作厂家推荐 - 行业平台推荐
  • 2026年口碑好的上海轻便婴儿车 品牌推荐:上海双胞胎婴儿车/上海遛娃神器婴儿车优质供应商推荐参考 - 行业平台推荐
  • 如何把千问(Qwen)用出“200%”的效果?
  • SpringBoot 统一功能处理!
  • 2025板材厂家排名 - 品牌推荐(官方)
  • 2026年热门的六角网眼布 工厂推荐:透气网眼布/三明治网眼布直销厂家选哪家 - 行业平台推荐
  • 价值投资新方向!AI应用架构师的多智能体系统精准分析思路
  • 巴甫洛夫-经典条件作用理论
  • 养虾盛行,AI焦虑症蔓延,六个普通人和AI扛过的这一年
  • [AI智能体与提效-147] - 编排的含义、实现方法与示例
  • 【OpenClaw学习笔记】第二天:认识Ollama
  • 数据科学与大数据技术专业毕业设计选题方向全汇总(2026最新版)
  • windows系统官网下载以及制作U盘启动盘
  • 通义千问Qwen的核心能力,适用场景与优势是哪些?
  • 2026年知名的塑料粉碎机 工厂推荐:边料粉碎机/机边粉碎机/注塑机边粉碎机稳定供应商推荐 - 行业平台推荐
  • 10大美国展会搭建服务商推荐,专注展台设计与搭建好评如潮