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

Linux:缓冲区的概念理解

文章目录

  • 缓冲区
    • 什么是缓冲区?
    • 缓冲区的意义是什么?
    • 缓冲区的刷新方式
  • 理解缓冲区
  • 用户缓冲区和内核缓冲区
  • 缓冲区在哪里?

本篇主要总结的是关于缓冲区的概念理解,以及再次基础上对文件的常用接口进行一定程度的封装

缓冲区

什么是缓冲区?

如何理解缓冲区?简单来说,缓冲区就是一段内存,用来存放一些信息,这就是对于缓冲区最初步的理解。那如何证明缓冲区的存在?用下面的代码来验证缓冲区

#include <stdio.h>
#include <unistd.h>void buffertest()
{printf("hello linux");sleep(3);
}int main()
{buffertest();return 0;
}

在这里插入图片描述
现象

运行结果如上所示,会先休眠三秒再输出结果,按程序的顺序结构来说,sleep一定是在printf之后执行的,也就意味着当执行到sleep的时候运行结果已经被写到了某个地方,只是还没有刷新到显示器上,因此用户看不见显示的内容,而当sleep执行完毕后,此时会把内容刷新到显示器上,这样就能看到运行的结果了

解释

而在执行了printf函数后其实就已经把内容输出了,输出的地方其实就是缓冲区中,只是还没有将信息存储到显示器这个文件内,因此没有输出结果,而当进程结束后,就会把缓冲区中的信息都刷新到显示器中,此时就实现了把信息打印到显示器上,所以才会看到,程序运行后没有输出结果,而是在执行完sleep后才会输出到显示器上

缓冲区的意义是什么?

如何理解缓冲区?有了这个缓冲区能干什么呢?答案是提高效率,对于这个答案其实并不陌生,在前面的学习中也存在有关于缓冲区的概念,只是对于缓冲区的认知程度比较低

举个例子来说,现在用户在上层使用C语言打印了很多信息,但是没有发出要刷新的需求,那么此时这些信息就都会存储在缓冲区中,而当缓冲区满了或者触发其他的刷新策略的时候,就会统一把缓冲区中的信息转移到内存中,再由内存进行其他后续的操作,在本文的后面会对这一整体的操作进行分析,此处只进行初步的描述

从外部把信息存储到内存中是需要成本的,而缓冲区的存在就是把这些信息积攒到一定程度再进行发送,既然设计出缓冲区的存在,那么就意味着把信息从缓冲区发送到内存中比直接把信息发送到内存中需要付出的成本低,这样可以提高运输的效率

缓冲区的刷新方式

缓冲区可以暂存数据,就意味着一定会有对应的刷新方式

  1. 无缓冲(立即刷新)
  2. 行缓冲(行刷新)
  3. 全缓冲(缓冲区满了才刷新)

一般而言是可以使用上面的刷新策略的,但是在实际的进程运行过程中可能会出现其他的意外情况,例如:

  1. 强制刷新
  2. 进程退出了,一般会刷新缓冲区

一般而言,对于显示器文件会采用的是行刷新策略,而对于磁盘上的文件会采用全缓冲的策略,对于这两种不同的刷新策略下一个模块就进行分析

理解缓冲区

下面来看这样的测试代码样例

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的操作会带来怎样的影响?这两种现象出现的原因是什么呢?

对于上述现象的理解和解释

  1. 首先,对于上面的异常现象,要从出现异常的操作出发,为什么会出现异常?原因是一个是将内容直接执行,运行到显示器上,一个是把执行的结果输出到一个文件中,那么这两个操作会带来区别吗?答案是一定会的,原因就是前面提到的刷新方式的变换,对于显示器来说是行刷新策略,对于磁盘来说是全刷新策略,那么这就会带来不一样的结果,具体的原因后续分析
  2. 全缓冲意味着缓冲区会变大,实际写入的简单数据不会把缓冲区写满,因此在执行fork操作的时候,数据依旧在缓冲区中,没有被刷新到文件中
  3. 在上述的代码中所使用到的缓冲区,全部都是C语言的缓冲区,这个缓冲区是C语言本身给我们提供的,因此和操作系统内部提供的缓冲区是两种缓冲区,没有关系
  4. 那么问题来了,这和fork有什么关系呢?fork会带来什么结果呢?
  5. 那么现在就要思考的是,fork会带来什么结果,根据前面的思想不难想到,fork带来的第一个直观的效果就是创建一个子进程,这是不需要质疑的事,而对于这个进程来说,fork结束后带来的另外一个结果就是结束进程,而结束进程带来的结果就是会刷新缓冲区,既然刷新缓冲区了,那么就会把这个进程所对应的缓冲区内容清空,那么下一个问题就是关于写时拷贝的问题,缓冲区清空算不算进程的数据发生改变了呢?如果算发生改变就会发生写时拷贝,如果不算改变就不会,那么下一个问题就是进程的数据在清空缓冲区的时候算不算发生了修改
  6. 要解决上面的这个问题,本质上是思考C语言的缓冲区中的数据算不算进程运行时候的数据,因为写时拷贝的触发原理就是进程运行时候,父进程和子进程中只要有一个进程中的数据被修改,就会给另外一个进程发生写时拷贝,而这里的缓冲区的数据一定是属于进程运行时的数据的,而与此同时需要注意的是,当把数据已经交给操作系统之后,此时数据就是操作系统的,而不是进程本身的数据了,对于这样的数据即使发生修改也并不隶属于写时拷贝的范畴
  7. 那么分析到这里,其实对于上面的这个现象已经理解的很到位了,现在还有最后一个问题,为什么这个进程中对于使用系统调用的数据没有发生写时拷贝,难道这个不算是C语言缓冲区的数据,以至于这个数据不算进程的数据就不会发生写时拷贝吗?答案是肯定的,这是因为缓冲区也有很多类,而除了系统调用外的其他写入的方式都是使用的是C语言自身所提供的一个缓冲区,因此在这样的基础下进行的数据是属于进程的数据的,而使用系统调用的接口使用的数据其实并不属于,它没有使用C语言缓冲区

总结

经过上面的这几条分析,其实已经把缓冲区的概念总结的算是比较到位了,刷新其实就是把C缓冲区的数据写入操作系统

用户缓冲区和内核缓冲区

什么是用户缓冲区,什么是内核缓冲区?

用户缓冲区

用户缓冲区其实就是平时日常的使用中提供的语言级别的缓冲区,在用户层面把信息进行写入,这样的级别就是用户缓冲区所做的事,作为用户上层,进行了一系列的各种写入,这些操作都是在给用户缓冲区中写入信息,而从用户缓冲区再向着操作系统写入信息这个过程,就是刷新,经过刷新就可以把信息写入操作系统,而在操作系统内部,又会有一套完整的文件系统,关于文件系统在上一篇文章中已经完整的描述过内部的过程,这里就不再详细叙述了

内核缓冲区

既然将内容从C语言写到操作系统中需要缓冲区,那么把读取的信息刷新到磁盘中是不是也是需要缓冲区的介入呢?答案是肯定的,这是一定会有的,而这其实也是刷新,把内核缓冲区的数据写到磁盘中,也是一种刷新,只不过刷新策略和前面的C缓冲区不太一样而已,这里就对内核缓冲区不再进行过多的介绍了,它本质和硬件设备相关更多一些

缓冲区在哪里?

那这个缓冲区在哪里呢?其实也是可以找到的,调用指令进行搜索:

whereis stdio.h

打开文件,寻找FILE有关的内容

在这里插入图片描述
那么下一步就是寻找这个结构体究竟在哪里

在这里插入图片描述
在这个libio.h文件中,寻找到了这个内容,而在进行输入和输出的时候,就会有一个FILE,而FILE本质上就是一个结构体,这个结构体叫FILE里面就包含了fd,这个FILE结构体就会提供一段缓冲区

相关文章:

Linux:缓冲区的概念理解

文章目录 缓冲区什么是缓冲区&#xff1f;缓冲区的意义是什么&#xff1f;缓冲区的刷新方式 理解缓冲区用户缓冲区和内核缓冲区缓冲区在哪里&#xff1f; 本篇主要总结的是关于缓冲区的概念理解&#xff0c;以及再次基础上对文件的常用接口进行一定程度的封装 缓冲区 什么是缓…...

中山大学李华山、王彪课题组开发 SEN 机器学习模型,高精度预测材料性能

内容一览&#xff1a;了解全局晶体对称性并分析等变信息&#xff0c;对于预测材料性能至关重要&#xff0c;但现有的、基于卷积网络的算法尚且无法完全实现这些需求。针对于此&#xff0c;中山大学的李华山、王彪课题组&#xff0c;开发了一款名为 SEN 的机器学习模型&#xff…...

二百一十、Hive——Flume采集的JSON数据文件写入Hive的ODS层表后字段的数据残缺

一、目的 在用Flume把Kafka的数据采集写入Hive的ODS层表的HDFS文件路径后&#xff0c;发现HDFS文件中没问题&#xff0c;但是ODS层表中字段的数据却有问题&#xff0c;字段中的JSON数据不全 二、Hive处理JSON数据方式 &#xff08;一&#xff09;将Flume采集Kafka的JSON数据…...

【开放集检测OSR】开放集检测和闭集检测的区别和联系:从模型角度进行理解

定义一个分类器&#xff1a; D t r a i n { ( x i , y i ) } i 1 N ⊂ X C D_{train} \{(x_i, y_i)\}^N _{i1} ⊂ X C Dtrain​{(xi​,yi​)}i1N​⊂XC X&#xff1a;输入空间 ( x i , y i ) (x_i, y_i) (xi​,yi​): 输入的图像x以及其对象的类别标签yC &#xff1a;已知…...

【Flink】Flink核心概念简述

目录 一、Flink 简介二、Flink 组件栈1. API & Libraries 层2. runtime层3. 物理部署层 三、Flink 集群架构四、Flink基本编程模型五、Flink 的部署模式六、Flink 任务的执行模式五、Flink 的优点 一、Flink 简介 Apache Flink 的前身是柏林理工大学一个研究性项目&#x…...

linux-tar命令、解压、压缩

压缩 文件夹 命令&#xff1a;tar -zcvf ~/test/tar_t.tar.gz /target/ 将/target/文件夹及其子文件夹和文件压缩成tar_t.tar.gz文件&#xff0c;并放于~/test/路径下 文件 命令&#xff1a;tar -zcvf ~/test/tar_t.tar.gz /target/file 将/target/file文件压缩成tar_t.tar…...

Kafka Connect :构建强大分布式数据集成方案

Kafka Connect 是 Apache Kafka 生态系统中的关键组件&#xff0c;专为构建可靠、高效的分布式数据集成解决方案而设计。本文将深入探讨 Kafka Connect 的核心架构、使用方法以及如何通过丰富的示例代码解决实际的数据集成挑战。 Kafka Connect 的核心架构 Kafka Connect 的核…...

基于 Flink CDC 构建 MySQL 的 Streaming ETL to MySQL

简介 CDC 的全称是 Change Data Capture &#xff0c;在广义的概念上&#xff0c;只要是能捕获数据变更的技术&#xff0c;我们都可以称之为 CDC 。目前通常描述的 CDC 技术主要面向数据库的变更&#xff0c;是一种用于捕获数据库中数据变更的技术。CDC 技术的应用场景非常广泛…...

创建vue项目:node.js下载安装、配置环境变量,下载安装cnpm,配置npm的目录、镜像,安装vue、搭建vue项目开发环境(保姆级教程一)

今天讲解 Windows 如何创建 vue 项目&#xff0c;搭建 vue 开发环境&#xff0c;这是这个系列的第一章&#xff0c;有什么问题请留言&#xff0c;请点赞收藏&#xff01;&#xff01;&#xff01; 文章目录 一、Vue简单介绍二、开始搭建1、安装node.js环境2、配置npm下载时的默…...

uni-app 微信小程序之好看的ui登录页面(一)

文章目录 1. 页面效果2. 页面样式代码 更多登录ui页面 uni-app 微信小程序之好看的ui登录页面&#xff08;一&#xff09; uni-app 微信小程序之好看的ui登录页面&#xff08;二&#xff09; uni-app 微信小程序之好看的ui登录页面&#xff08;三&#xff09; uni-app 微信小程…...

[ES]ElasticSearch强转日期的时区问题

问题 由于ES不能修改时区&#xff0c;且默认时区始终为UTC。 当才查询数据时&#xff0c;通过强转获得的日期并不是想要的&#xff0c;通过分析发现&#xff0c;正是由于默认时区导致结果相差了8个小时。 查询语句&#xff1a; POST http://localhost:9200/_sql?formattext {&…...

YOLOv5结合BiFPN,如何替换YOLOv5的Neck实现更强的检测能力?

一、BiFPN是什么&#xff1f; 1、什么是BiFPN BiFPN是一种基于特征金字塔网络&#xff08;FPN&#xff09;和双向特征金字塔网络&#xff08;BiFPN&#xff09;的对象检测神经网络结构&#xff0c;它被用于提高目标检测的准确度和速度。在目标检测领域&#xff0c;FPN用于将不同…...

3.PyTorch——常用神经网络层

import numpy as np import pandas as pd import torch as t from PIL import Image from torchvision.transforms import ToTensor, ToPILImaget.__version__2.1.13.1 图像相关层 图像相关层主要包括卷积层&#xff08;Conv&#xff09;、池化层&#xff08;Pool&#xff09;…...

状态机的练习:按键控制led灯

设计思路&#xff1a; 三个按键控制led输出。 三个按键经过滤波(消抖)&#xff0c;产生三个按键标志信号。 三个led数据的产生模块&#xff08;流水&#xff0c;跑马&#xff0c;闪烁模块&#xff09;&#xff0c;分别产生led信号。 这六路信号&#xff08;三路按键信号&am…...

看图学源码之 CopyOnWriteArraySet源码分析

基本介绍 使用内部CopyOnWriteArrayList进行所有操作的Set 特点 它最适合以下应用程序&#xff1a;集合大小通常较小、只读操作的数量远远多于可变操作&#xff0c;并且您需要在遍历期间防止线程之间的干扰。它是线程安全的。突变操作&#xff08; add 、 set 、 remove等&…...

almaLinux centos8 下载ffmpeg离线安装包、离线安装

脚本 # 添加RPMfusion仓库 sudo yum install https://download1.rpmfusion.org/free/el/rpmfusion-free-release-8.noarch.rpm wget -ymkdir -p /root/ffmpeg cd /root/ffmpegwget http://rpmfind.net/linux/epel/7/x86_64/Packages/s/SDL2-2.0.14-2.el7.x86_64.rpmyum instal…...

CSS3 属性: transition过渡 与 transform动画

CSS3 提供了很多强大的功能&#xff0c;使开发人员可以创建更加吸引人的视觉效果&#xff0c;而不需要依赖于 JavaScript 或 Flash。其中&#xff0c;transition 和 transform 是两个常用的属性&#xff0c;它们分别用于创建平滑的过渡效果和元素的变形效果。下面我们将详细介绍…...

TCP通讯

第二十一章 网络通信 本章节主要讲解的是TCP和UDP两种通信方式它们都有着自己的优点和缺点 这两种通讯方式不通的地方就是TCP是一对一通信 UDP是一对多的通信方式 接下来会一一讲解 TCP通信 TCP通信方式呢 主要的通讯方式是一对一的通讯方式&#xff0c;也有着优点和缺点 …...

(NeRF学习)3D Gaussian Splatting Instant-NGP

学习参考&#xff1a; 3D Gaussian Splatting入门指南【五分钟学会渲染自己的NeRF模型&#xff0c;有手就行&#xff01;】 三维重建instant-ngp环境部署与colmap、ffmpeg的脚本参数使用 一、3D Gaussian Splatting &#xff08;一&#xff09;3D Gaussian Splatting环境配置…...

uni-app 微信小程序之好看的ui登录页面(三)

文章目录 1. 页面效果2. 页面样式代码 更多登录ui页面 uni-app 微信小程序之好看的ui登录页面&#xff08;一&#xff09; uni-app 微信小程序之好看的ui登录页面&#xff08;二&#xff09; uni-app 微信小程序之好看的ui登录页面&#xff08;三&#xff09; uni-app 微信小程…...

浅谈 React Hooks

React Hooks 是 React 16.8 引入的一组 API&#xff0c;用于在函数组件中使用 state 和其他 React 特性&#xff08;例如生命周期方法、context 等&#xff09;。Hooks 通过简洁的函数接口&#xff0c;解决了状态与 UI 的高度解耦&#xff0c;通过函数式编程范式实现更灵活 Rea…...

装饰模式(Decorator Pattern)重构java邮件发奖系统实战

前言 现在我们有个如下的需求&#xff0c;设计一个邮件发奖的小系统&#xff0c; 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式&#xff08;Decorator Pattern&#xff09;允许向一个现有的对象添加新的功能&#xff0c;同时又不改变其…...

【Linux】C语言执行shell指令

在C语言中执行Shell指令 在C语言中&#xff0c;有几种方法可以执行Shell指令&#xff1a; 1. 使用system()函数 这是最简单的方法&#xff0c;包含在stdlib.h头文件中&#xff1a; #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...

【网络安全产品大调研系列】2. 体验漏洞扫描

前言 2023 年漏洞扫描服务市场规模预计为 3.06&#xff08;十亿美元&#xff09;。漏洞扫描服务市场行业预计将从 2024 年的 3.48&#xff08;十亿美元&#xff09;增长到 2032 年的 9.54&#xff08;十亿美元&#xff09;。预测期内漏洞扫描服务市场 CAGR&#xff08;增长率&…...

2024年赣州旅游投资集团社会招聘笔试真

2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...

oracle与MySQL数据库之间数据同步的技术要点

Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异&#xff0c;它们的数据同步要求既要保持数据的准确性和一致性&#xff0c;又要处理好性能问题。以下是一些主要的技术要点&#xff1a; 数据结构差异 数据类型差异&#xff…...

OkHttp 中实现断点续传 demo

在 OkHttp 中实现断点续传主要通过以下步骤完成&#xff0c;核心是利用 HTTP 协议的 Range 请求头指定下载范围&#xff1a; 实现原理 Range 请求头&#xff1a;向服务器请求文件的特定字节范围&#xff08;如 Range: bytes1024-&#xff09; 本地文件记录&#xff1a;保存已…...

图表类系列各种样式PPT模版分享

图标图表系列PPT模版&#xff0c;柱状图PPT模版&#xff0c;线状图PPT模版&#xff0c;折线图PPT模版&#xff0c;饼状图PPT模版&#xff0c;雷达图PPT模版&#xff0c;树状图PPT模版 图表类系列各种样式PPT模版分享&#xff1a;图表系列PPT模板https://pan.quark.cn/s/20d40aa…...

技术栈RabbitMq的介绍和使用

目录 1. 什么是消息队列&#xff1f;2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...

push [特殊字符] present

push &#x1f19a; present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中&#xff0c;push 和 present 是两种不同的视图控制器切换方式&#xff0c;它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...