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

Linux_内核缓冲区

目录

1、用户缓冲区概念 

2、用户缓冲区刷新策略

3、用户缓冲区的好处 

4、内核缓冲区

5、验证内核缓冲区 

6、用户缓冲区存放的位置 

7、全缓冲 

结语


前言:

        Linux下的内核缓冲区存在于系统中,该缓冲区和用户层面的缓冲区不过同一个概念,用户层面的缓冲区称之为用户缓冲区,而系统中也有自己的缓冲区即内核缓冲区,两者虽然同为缓冲区却差之毫厘谬以千里,了解内核缓冲区前先谈谈用户缓冲区。

1、用户缓冲区概念 

        用户缓冲区是用户空间的标准库(stdio.h)缓冲区的缩写,也就是说标准库会提供一个缓冲区用来存放用户调用文件操作相关的库函数所产生或者接收到的数据,用户缓冲区是程序员在调用库函数时接触最频繁的,比如调用scanf、printf以及其他与文件流相关的函数,并不是直接把数据输入到目的地,中途先把数据放到用户缓冲区内,然后通过刷新缓冲区才能把数据送到目的地,示意图如下:

2、用户缓冲区刷新策略

        有三种刷新用户缓冲区的策略:

1、无缓冲:只要把数据写到缓冲区内就会自动刷新缓冲区,比如系统函数write和read。

2、行缓冲:遇到\n时自动刷新缓冲区,打印到屏幕上时用行缓冲。

3、全缓冲:缓冲区满了才会自动刷新,比如将数据写入磁盘文件。

补充:进程结束时会自动刷新缓冲区。

3、用户缓冲区的好处 

        1、提高效率,有了缓冲区后,数据就不必频繁的传输,也不必频繁的进行系统调用,因为处理少量的数据可以先把数据放到缓冲区内,然后统一进行传输,减少了小块数据的传输次数,以至于提高系统效率。

        2、同一格式化,意思是所有的int类型、float类型都需要转换成字符串的形式存放到缓冲区内,接收方只需要采用字符串形式的处理方式统一处理。 

4、内核缓冲区

        上述说到printf以及其他各种文件流函数会经过用户缓冲区然后再到硬件文件(显示器就是一个硬件文件),其实经过了用户缓冲区后还要调用系统函数wrtie,通过wrtie将用户缓冲区的内容写到内核缓冲区内,最后由系统自动刷新内核缓冲区,才把内容写进硬件文件中,很明显这个内核缓冲区是在系统里的,并且因为库函数接口自动帮助我们调用底层函数,所以这些细节上层并不是关系,因此完整的流程图如下:

         只有当最后一步把数据写到磁盘上的显示器文件时,才算是真正的在屏幕上打印出来。注意:刷新内核缓冲区由系统自动完成。

5、验证内核缓冲区 

        通过上图可以发现printf库函数和用户缓冲区“打交道”,wrtie系统函数和内核缓冲区“打交道”,所以通过下面测试代码,可以证明内核缓冲区和用户缓冲区是两个缓冲区,示例代码如下:

#include <stdio.h>
#include <string.h>
#include <unistd.h>int main()
{const char *fstr = "hello fwrite";const char *str = "hello write";// Cprintf("hello printf"); // stdout -> 1sleep(1);fprintf(stdout, "hello fprintf"); // stdout -> 1sleep(1);fwrite(fstr, strlen(fstr), 1, stdout); // fwrite, stdout->1sleep(1);// 操作提供的系统函数write(1, str, strlen(str)); // 1close(1); //关闭该进程的显示器文件sleep(2);//fork();return 0;
}

         运行结果:

        从运行结果可以发现,只有调用wrtie的数据被打印出来了,前面的三句话都没被打印出来,原因就是close(1)这句代码,并且细心观察会发现所有字符串内容都没加‘\n’,这就导致写入用户缓冲区时不会立刻刷新用户缓冲区,错过了这次的刷新,下次刷新只能等该进程结束时才会自动刷新用户缓冲区了,但是在该进程结束前就关闭了1号文件描述符(即显示器文件),导致之前堆积在用户缓冲区里的数据刷新后找不到对应的内核缓冲区了,因此最终的现象就是用户缓冲区的内容全部没打印在屏幕上。

        但是write的数据却正常打印了,原因就是write跳过了用户缓冲区,直接往内核缓冲区里写,并且在close关闭前会自动刷新内核缓冲区,所以close虽然关闭了1号文件描述符,但是write的数据已经写到显示器文件里了,因此可以正常打印write负责的数据。 

6、用户缓冲区存放的位置 

        我们使用的用户缓冲区存放在c语言标准库为我们封装好的指针FILE* fp所指向的结构体里,示意图如下:

        该结构体里包含了大量的文件相关信息,其中就包括文件描述符以及用户缓冲区,因为printf是默认使用stdout文件流指针的,所以即使不传文件指针给printf也可以在屏幕上打印。 

7、全缓冲 

        当进程里的文件描述符1被重定向至文件中,这时候stdout打印方式从行缓冲变成了全缓冲,即遇到\n后不会刷新用户缓冲区了,只有把用户缓冲区写满才会刷新,或者当进程结束的时候才会刷新缓冲区,让缓冲区里的内容读进文件里。

        示例代码如下:

#include <stdio.h>
#include <string.h>
#include <unistd.h>int main()
{const char *fstr = "hello fwrite\n";const char *str = "hello write\n";// Cprintf("hello printf\n"); // stdout -> 1sleep(1);fprintf(stdout, "hello fprintf\n"); // stdout -> 1sleep(1);fwrite(fstr, strlen(fstr), 1, stdout); // fread, stdout->1sleep(1);// 操作提供的systemcallwrite(1, str, strlen(str)); // 1sleep(2);//close(1);fork();return 0;
}

        运行结果:

        从结果发现调用库函数打印的数据在文件中写了两份,而调用系统函数打印的数据只写了一份,根本原因很简单,就是因为程序的末尾使用fork创建了子进程,但是具体为什么创建子进程后会让有些数据打印两份有些数据打印一份呢?

原因如下:

        1、文件是全缓冲,所以数据会在缓冲区内堆积。

        2、进程退出的时候会刷新缓冲区,会引发写时拷贝,因此会给另一个进程拷贝一份缓冲区的内容。

        3、write负责的数据没有写两份的原因是write是系统调用接口(一个struct file只有一个内核缓冲区),他跳过用户缓冲区,并把数据写到内核缓冲区内,所以不会引发写时拷贝。

        示意图如下:

结语

         以上就是关于内核缓冲区以及用户缓冲区的全部讲解,理解内核缓冲区的前提是了解文件流流向的整个过程,因此必须了解c标准库提供给用户的标准库缓冲区又称用户缓冲区的概念,并且若想拿到缓冲区里的内容给到“下一站”,则必须刷新缓冲区。

相关文章:

Linux_内核缓冲区

目录 1、用户缓冲区概念 2、用户缓冲区刷新策略 3、用户缓冲区的好处 4、内核缓冲区 5、验证内核缓冲区 6、用户缓冲区存放的位置 7、全缓冲 结语 前言&#xff1a; Linux下的内核缓冲区存在于系统中&#xff0c;该缓冲区和用户层面的缓冲区不过同一个概念&#x…...

步步精:连接器领域的卓越品牌

自1987年成立以来&#xff0c;步步精坐落于美丽的旅游城市——温州市乐清虹桥镇&#xff0c;被誉为“国家电子主体生产基地”、“国家精密模具制造基地”。公司拥有7大厂区、9大事业部&#xff0c;800名专职员工&#xff0c;致力于提供高品质的连接器解决方案。注册商标“BBJCO…...

【Linux】基础IO_3

文章目录 六、基础I/O3. 软硬链接4. 动静态库 未完待续 六、基础I/O 3. 软硬链接 使用 ln 就可以创建链接&#xff0c;使用 ln -s 可以创建软链接&#xff0c;直接使用 ln 则是硬链接。 我们对硬链接进行测试一下&#xff1a; 根据测试&#xff0c;我们知道了 硬链接就像一…...

ffmpeg音视频开发从入门到精通——ffmpeg实现音频抽取

文章目录 FFmpeg 实现音频流抽取1. 包含FFmpeg头文件与命名空间声明2. 主函数与参数处理3. 打开输入文件4. 获取文件信息5. 查找音频流6. 分配输出文件上下文7. 猜测输出文件格式8. 创建新的音频流9. 打开输出文件10. 写入文件头信息11. 读取并写入音频数据12. 写入文件尾部信息…...

计算机系统基础实训七-MallocLab实验

实验目的与要求 1、让学生理解动态内存分配的工作原理&#xff1b; 2、让学生应用指针、系统级编程的相关知识&#xff1b; 3、让学生应用各种动态内存分配器的实现方法&#xff1b; 实验原理与内容 &#xff08;1&#xff09;动态内存分配器基本原理 动态内存分配器维护…...

周末总结(2024/06/22)

工作 人际关系核心实践&#xff1a; 要学会随时回应别人的善意&#xff0c;执行时间控制在5分钟以内 坚持每天早会打招呼 遇到接不住的话题时拉低自己&#xff0c;抬高别人(无阴阳气息) 工作上的要点 现状&#xff08;接受破烂现状&#xff0c;改变状态&#xff09; - 这周没…...

2024.06.22【读书笔记】丨生物信息学与功能基因组学(第十七章 人类基因组 第二部分)【AI测试版】

第二部分:人类基因组的主要结论与网络资源 摘要: 第二部分深入总结了人类基因组计划的关键发现,并介绍了用于探索人类基因组的网络资源。这些结论不仅为我们理解人类生物学提供了新的视角,而且揭示了人类基因组的复杂性和动态性。 学习目标: 掌握人类基因组计划的主要科…...

SpringCloud-nacos基础

SpringCloud-nacos nacos在微服务种有两大作用&#xff1a; 配置中心服务注册中心 配置中心 维度管理 nacos配置中心可以在三个维度进行管理&#xff1a; spring.profiles.active dev/prod/test,通过这个属性可以配置不同环境下的配置文件。 配置的文件名应该为${spring…...

git的Cherry pick

Cherry pick Git Cherry Pick详解 https://blog.csdn.net/jam_yin/article/details/131594716 目标: 将开发分支A中提交的部分内容合并到B分支(可能是测试分支) 步骤: vscode安装 点击下图标进入graph...

LLC开关电源开发:第四节,LLC软件设计报告

LLC源代码链接 数控全桥LLC开发板软件设计报告  1. LLC硬件及软件框架2. LLC软件设计2.1 工程文件说明2.2 LLC中断设计2.2.1 20us中断2.2.2 5ms中断 2.3 LLC状态机设计2.3.1 初始化状态2.3.2 空闲状态2.3.3 软启动状态2.3.4 正常运行状态2.3.5 故障状态 2.4 环路设计2.4.1 环路…...

力扣85.最大矩形

力扣85.最大矩形 遍历所有行作为底边 做求矩形面积&#xff08;84. class Solution {public:int maximalRectangle(vector<vector<char>>& matrix) {if (matrix.empty()) return 0;int n matrix.size(),m matrix[0].size();int res0;vector<int> li…...

和琪宝的厦门之旅~

本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。 本作品 (李兆龙 博文, 由 李兆龙 创作)&#xff0c;由 李兆龙 确认&#xff0c;转载请注明版权。 引言 承接去年国庆的遗憾&#xff0c;我们将这次的旅行城市定为厦门。 琪宝是下午四点左右到…...

4、MFC:菜单栏、工具栏与状态栏

菜单栏、工具栏与状态栏 1、菜单栏1.1 简介1.2 创建属性设置菜单消息成员函数 1.3 实例 2、工具栏2.1 简介工具栏属性2.2 创建消息CToolBar类的主要成员函数 2.3 实例 3、状态栏3.1 简介3.2 创建CStatusBar类状态栏创建 3.3 实例 1、菜单栏 1.1 简介 菜单在界面设计中是经常使…...

Java中的动态代理:原理与应用

Java中的动态代理&#xff1a;原理与应用 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01; 在Java开发中&#xff0c;动态代理是一种强大且灵活的技术&#xff…...

DataWhale - 吃瓜教程学习笔记(二)

学习视频&#xff1a;第3章-一元线性回归_哔哩哔哩_bilibili 西瓜书对应章节&#xff1a; 3.1 - 3.2 一元线性回归 - 最小二乘法 - 极大似然估计 - 梯度 多元函数的一阶导数 - 海塞矩阵 多元函数的二阶导数 - 机器学习三要素...

[保姆级教程]uniapp自定义标签页切换组件

文章目录 导文样式改成动态列表切换点击效果加上点击自动滑动scroll-view加上切换组件效果 导文 unaipp自带的标签页和ui设计相差太大&#xff0c;直接修改组件比手写一个还麻烦&#xff0c;下面手写一个。 样式 先用scroll-view做一个滑动&#xff0c;不然多的话滑动不了。 &l…...

4种典型家庭教育方式,无论开始是哪一种,都会过渡到最后一种

家庭教育&#xff0c;是孩子教育的一个重要组成部分&#xff0c;事实上是对孩子影响最大的一种教育方式&#xff0c;绝大部分家庭教育都是由孩子的父母来完成的。 家庭教育的特点 家庭教育具有很明显的启蒙性、长期性、全面性。 1.启蒙性。我们的孩子对外部世界的认识和了解&am…...

[Django学习]查询过滤器(lookup types)

1.exact exact用于精确匹配字段的值。适用于需要精确查找某个字段值的场景。 Book.objects.filter(title__exactHarry Potter) 上面的查询会查找标题完全为“Harry Potter”的书籍。 2.iexact iexact忽略大小写地精确匹配字段的值。适用于需要忽略大小写进行精确匹配的场…...

异步开发的终极答案—协程

我们在之前的文章中讲过,在并发场景下,传统的基于多线程的命令式开发模型虽然比较简单,但并发数高了之后资源占用较高,大量线程会阻塞;而响应式编程模式我们可以通过异步化处理提升系统资源的利用效率,但异步开发有违人的直觉,门槛比较高。作为成年人,我们肯定希望全都…...

构建高效的大数据量延迟任务调度平台

目录 引言系统需求分析系统架构设计 总体架构任务调度模块任务存储模块任务执行模块 任务调度算法 时间轮算法优先级队列分布式锁 数据存储方案 关系型数据库NoSQL数据库混合存储方案 容错和高可用性 主从复制数据备份与恢复故障转移 性能优化 水平扩展缓存机制异步处理 监控与…...

CTF show Web 红包题第六弹

提示 1.不是SQL注入 2.需要找关键源码 思路 进入页面发现是一个登录框&#xff0c;很难让人不联想到SQL注入&#xff0c;但提示都说了不是SQL注入&#xff0c;所以就不往这方面想了 ​ 先查看一下网页源码&#xff0c;发现一段JavaScript代码&#xff0c;有一个关键类ctfs…...

docker详细操作--未完待续

docker介绍 docker官网: Docker&#xff1a;加速容器应用程序开发 harbor官网&#xff1a;Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台&#xff0c;用于将应用程序及其依赖项&#xff08;如库、运行时环…...

rknn优化教程(二)

文章目录 1. 前述2. 三方库的封装2.1 xrepo中的库2.2 xrepo之外的库2.2.1 opencv2.2.2 rknnrt2.2.3 spdlog 3. rknn_engine库 1. 前述 OK&#xff0c;开始写第二篇的内容了。这篇博客主要能写一下&#xff1a; 如何给一些三方库按照xmake方式进行封装&#xff0c;供调用如何按…...

前端倒计时误差!

提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...

Cesium1.95中高性能加载1500个点

一、基本方式&#xff1a; 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...

UDP(Echoserver)

网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法&#xff1a;netstat [选项] 功能&#xff1a;查看网络状态 常用选项&#xff1a; n 拒绝显示别名&#…...

【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)

🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...

Matlab | matlab常用命令总结

常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...

Android第十三次面试总结(四大 组件基础)

Activity生命周期和四大启动模式详解 一、Activity 生命周期 Activity 的生命周期由一系列回调方法组成&#xff0c;用于管理其创建、可见性、焦点和销毁过程。以下是核心方法及其调用时机&#xff1a; ​onCreate()​​ ​调用时机​&#xff1a;Activity 首次创建时调用。​…...

用机器学习破解新能源领域的“弃风”难题

音乐发烧友深有体会&#xff0c;玩音乐的本质就是玩电网。火电声音偏暖&#xff0c;水电偏冷&#xff0c;风电偏空旷。至于太阳能发的电&#xff0c;则略显朦胧和单薄。 不知你是否有感觉&#xff0c;近两年家里的音响声音越来越冷&#xff0c;听起来越来越单薄&#xff1f; —…...