操作系统 -- 缓冲区(buffer)与缓存(cache)_输入缓冲区与输出缓冲区是一个内存吗-程序员宅基地

技术标签: 操作系统  缓存  

一、缓冲区(Buffer)

1.什么是缓冲区

缓冲区(buffer),它是内存空间的一部分。也就是说,在内存空间中预留了一定的存储空间,这些存储空间用来缓冲输入或输出的数据,这部分预留的空间就叫做缓冲区,显然缓冲区是具有一定大小的。

缓冲区根据其对应的是输入设备还是输出设备,分为输入缓冲区和输出缓冲区。

2.为什么要引入缓冲区

高速设备与低速设备的不匹配,势必会让高速设备花时间等待低速设备,我们可以在这两者之间设立一个缓冲区。

3. 缓冲区的作用

  1. 可以解除两者的制约关系,数据可以直接送往缓冲区,高速设备不用再等待低速设备,提高了计算机的效率。例如:我们使用打印机打印文档,由于打印机的打印速度相对较慢,我们先把文档输出到打印机相应的缓冲区,打印机再自行逐步打印,这时我们的CPU可以处理别的事情。
  2. 可以减少数据的读写次数,如果每次数据只传输一点数据,就需要传送很多次,这样会浪费很多时间,因为开始读写与终止读写所需要的时间很长,如果将数据送往缓冲区,待缓冲区满后再进行传送会大大减少读写次数,这样就可以节省很多时间。例如:我们想将数据写入到磁盘中,不是立马将数据写到磁盘中,而是先输入缓冲区中,当缓冲区满了以后,再将数据写入到磁盘中,这样就可以减少磁盘的读写次数,不然磁盘很容易坏掉。

简单来说,缓冲区就是一块内存区,它用在输入输出设备和CPU之间,用来存储数据。它使得低速的输入输出设备和高速的CPU能够协调工作,避免低速的输入输出设备占用CPU,解放出CPU,使其能够高效率工作。

4.缓冲区的类型

缓冲区 分为三种类型:全缓冲、行缓冲和不带缓冲。

  • 全缓冲
    在这种情况下,当填满标准I/O缓存后才进行实际I/O操作。全缓冲的典型代表是对磁盘文件的读写。
  • 行缓冲
    在这种情况下,当在输入和输出中遇到换行符时,执行真正的I/O操作。这时,我们输入的字符先存放在缓冲区,等按下回车键换行时才进行实际的I/O操作。典型代表是键盘输入数据。
  • 不带缓冲
    也就是不进行缓冲,标准出错情况stderr是典型代表,这使得出错信息可以直接尽快地显示出来。

下面用一段Python代码演示

# 全缓冲
def output1():
	while True:
		print('Ping',end='')
		time.sleep(0.001)
# 这个方法中不是每隔1毫秒打印一个Ping,而是等缓冲区满了才会一次性全部输出多个Ping

# 行缓冲
def output2():
	while True:
		print('Ping',end='')
		print('Pong',end='\n')
		time.sleep(0.001)
#这里是每隔1毫秒输出一个PingPong

# 不带缓冲
def output3():
	while True:
		print('Ping',end='',flush=True)
		time.sleep(0.001)
#这里就是每隔1毫秒输出一个Ping

5.缓冲区的刷新

下列情况会引发缓冲区的刷新:

缓冲区满时;
关闭文件。
可见,缓冲区满或关闭文件时都会刷新缓冲区,进行真正的I/O操作。

大家要仔细理解缓冲区刷新的意思,刷新字面上的意思是用刷子刷,把原来旧的东西变新了,这里就是改变的意思,例如像缓冲区溢出的时候,多余出来的数据会直接将之前的数据覆盖,这样缓冲区里的数据就发生了改变。

二、缓存(Cache)

1.CPU的cache

CPU的cache,它中文名称是高速缓冲存储器,读写速度很快,几乎与CPU一样。由于CPU的运算速度太快,内存的数据存取速度无法跟上CPU的速度,所以在cpu与内存间设置了cache为cpu的数据快取区。当计算机执行程序时,数据与地址管理部件会预测可能要用到的数据和指令,并将这些数据和指令预先从内存中读出送到Cache。一旦需要时,先检查Cache,若有就从Cache中读取,若无再访问内存,现在的CPU还有一级cache,二级cache。简单来说,Cache就是用来解决CPU与内存之间速度不匹配的问题,避免内存与辅助内存频繁存取数据,这样就提高了系统的执行效率。

2.磁盘的cache

磁盘也有cache,硬盘的cache作用就类似于CPU的cache,它解决了总线接口的高速需求和读写硬盘的矛盾以及对某些扇区的反复读取。

3.浏览器的cache

浏览器缓存(Browser Caching)是为了节约网络的资源加速浏览,浏览器在用户磁盘上对最近请求过的文档进行存储,当访问者再次请求这个页面时,浏览器就可以从本地磁盘显示文档,这样就可以加速页面的阅览,并且可以减少服务器的压力。这个过程与下载非常类似,不过下载是用户的主动过程,并且下载的数据一般是长时间保存,游览器的缓存的数据只是短时间保存,可以人为的清空

三、 缓存(cache)与缓冲(buffer)的主要区别

Buffer的核心作用是用来缓冲,缓和冲击。比如你每秒要写100次硬盘,对系统冲击很大,浪费了大量时间在忙着处理开始写和结束写这两件事嘛。用个buffer暂存起来,变成每10秒写一次硬盘,对系统的冲击就很小,写入效率高了,日子过得爽了。极大缓和了冲击。

Cache的核心作用是加快取用的速度。比如你一个很复杂的计算做完了,下次还要用结果,就把结果放手边一个好拿的地方存着,下次不用再算了。加快了数据取用的速度。

简单来说就是buffer偏重于写,而cache偏重于读。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/gghhb12/article/details/130959513

智能推荐

docker中mysql容器自动停止原因及解决方法_为什么我部署在docker里面的mysql,会被关闭-程序员宅基地

文章浏览阅读6.5k次,点赞3次,收藏23次。docker update -m 400M --memory-reservation 400M --memory-swap 500M 容器名。将docker.cnf 复制到mysql容器内(容器名可用docker ps -a 查看到name列,即为容器名)sudo docker cp ./docker.cnf 容器名:/etc/mysql/conf.d。第五步:限制mysql内存占用(本机器内存为1G,可视自己的机器内容设置)查看设置内容后docker容器内存使用情况:docker stats。_为什么我部署在docker里面的mysql,会被关闭

【K8S系列】深入解析K8S存储-程序员宅基地

文章浏览阅读2.3w次,点赞91次,收藏122次。在 Kubernetes 中,存储具有非常广泛的应用场景。可以根据实际需求选择适合自己的存储方案,以便更好地管理容器化应用程序中的数据和资源。本文会从以下三个方面,带你了解k8s存储:1.k8s存储类型;2.存储使用场景;3.存储使用案例

oracle 重新编译用户无效对象_oracle重新编译失效对象-程序员宅基地

文章浏览阅读1.2w次。oracle sys用户无效对象select owner,object_name, replace(object_type,' ','') object_type,to_char(created,'yyyy-mm-dd') as created,to_char(last_ddl_time,'yyyy-mm-dd') as last_ddl_time,statusfrom dba_o_oracle重新编译失效对象

【愚公系列】2023年10月 WPF控件专题 RadioButton控件详解_wpf radiobutton-程序员宅基地

文章浏览阅读5.1w次,点赞2次,收藏3次。WPF控件是Windows Presentation Foundation(WPF)中的基本用户界面元素。它们是可视化对象,可以用来创建各种用户界面。WPF控件可以分为两类:原生控件和自定义控件。原生控件是由Microsoft提供的内置控件,如Button、TextBox、Label、ComboBox等。这些控件都是WPF中常见的标准用户界面元素。自定义控件则允许开发人员使用XAML和C#等编程语言来创建个性化的用户界面元素。自定义控件可以根据需求提供更多的功能和自定义化选项,以及更好的用户体验。_wpf radiobutton

ES6(阮一峰)_es6 阮一峰-程序员宅基地

文章浏览阅读3.2k次。一、let 和const 命令let 命令块级作用域块级作用域与函数声明let 命令一、基本用法二、不存在变量提升:先声明再使用三、暂时性死区:先声明再赋值使用四、不允许重复声明:只要有let 就不能重复声明不允许再函数内部重新声明参数块级作用域es5没有块级作用域,var 声明会:1.内层变量可能会覆盖外层变量;2.用来计数的循环变量泄露为全局变量。块级作用域的作用:外层代码块不受内层代码块的影响。ES6 允许块级作用域的任意嵌套。内层作用域可以定义外层作用域的同名变量。匿名立_es6 阮一峰

Vue + Axios + ASP.NET Core WebAPI + 文件上传下载_axios filecontentresult-程序员宅基地

文章浏览阅读1.8k次。准备文件上传的API#region 文件上传 可以带参数[HttpPost(“upload”)]public JsonResult uploadProject(IFormFile file, string userId){if (file != null){var fileDir = “D:\aaa”;if (!Directory.Exists(fileDir)){Directory.CreateDirectory(fileDir);}//文件名称string projectFi_axios filecontentresult

随便推点

【DP、线段树优化】琪露诺_c++ 琪露诺树-程序员宅基地

文章浏览阅读274次。跟去年(2017)PJ第四题几乎是一样的?/吐血DP方程可以很简单的推出来,f[i]=max{f[k]}+a[i]然而这样做是O(n^2)的看一下数据,200000的话要不nlogn 要不n由于题解里面单调队列和优先队列都有人用了,那就来一发线段树吧(或者实情是:单调队列不会打?)只要维护i-r~i-l中f[i]的区间最大值即可(单点修改-区间查询)40行AC#include&lt..._c++ 琪露诺树

【区块链DAPP】智能合约概述_智能合约账户状态的组成部分及说明-程序员宅基地

文章浏览阅读5.6k次,点赞5次,收藏45次。智能合约概述_智能合约账户状态的组成部分及说明

Git学习笔记(流程图+示例)_git常用流程图-程序员宅基地

文章浏览阅读1.6k次,点赞33次,收藏24次。学习git时的笔记_git常用流程图

C语言中的++和--运算符_c语言---程序员宅基地

文章浏览阅读1.7w次,点赞92次,收藏288次。++和--运算符分别是 += 1 和 -= 1 的简写。设计这样两个运算符的本意是方便程序员,但i++和++i使用不恰当有时候会造成混淆,反倒令刚入门的C程序员有点儿混乱。如果i++或者++i单独为一条指令,则效果并没有什么区别,都是令i = i + 1;但是如果和其它的运算符结合,则二者还是有区别的。具体来说,i++ 是先使用 i,然后执行 i = i + 1;而 ++i 则是先执行 i = i + 1,然后再使用 i 。举个例子看下:int i = 0;printf("i is: %d\n"._c语言--

Dijkstra算法_dijkstra 采用邻接表 在一个边上带权网络中,求给定的两个顶点之间的最短路径。 编-程序员宅基地

文章浏览阅读1.4k次。Dijkstra算法是求解带权有向图中两点之间最短路径的经典算法,它采用贪心策略,维护一个向量dis用来表示从起点到其余顶点的路径“长度”。其主要原理如下:1.定义一个向量dis[],下标表示顶点,即dis[v]的值表示为从起点到v点的已知最短路径长度。初始化向量时,若v不是起点的相邻顶点,则dis[v]=∞,起点dis[0]=0。2.定义向量edge[],下标和值都表示顶点,假设edge..._dijkstra 采用邻接表 在一个边上带权网络中,求给定的两个顶点之间的最短路径。 编

吃了这些数据集和模型,跟 AI 学跳舞,做 TensorFlowBoys|湾区人工智能-程序员宅基地

文章浏览阅读669次。By 超神经场景描述:利用深度学习算法 GAN 可实现动作追踪与迁移,将某人物动作复制到其他人,应用到舞蹈领域,人人皆可成舞王。关键词:GAN 动作迁移 舞蹈最近,《..._街舞ai模型

推荐文章

热门文章

相关标签