什么是缓冲区(buffer),什么是缓存(cache)

缓冲区

缓冲区是内存空间的一部分。也就是说,在内存空间中预留了一定的存储空间,这些存储空间用来缓冲输入或输出的数据,这部分预留的空间就叫做缓冲区。缓冲区根据其对应的是输入设备还是输出设备,分为输入缓冲区和输出缓冲区

为什么要引入缓冲区

比如我们从磁盘里取信息,我们先把读出的数据放在缓冲区,计算机再直接从缓冲区中取数据,等缓冲区的数据取完后再去磁盘中读取,这样就可以减少磁盘的读写次数,再加上计算机对缓冲区的操作大大快于对磁盘的操作,故应用缓冲区可大大提高计算机的运行速度

又比如,我们使用打印机打印文档,由于打印机的打印速度相对较慢,我们先把文档输出到打印机相应的缓冲区,打印机再自行逐步打印,这时我们的CPU可以处理别的事情。现在您基本明白了吧,缓冲区就是一块内存区,它用在输入输出设备和CPU之间,用来缓存数据。它使得低速的输入输出设备和高速的CPU能够协调工作,避免低速的输入输出设备占用CPU,解放出CPU,使其能够高效率工作。

缓冲区的类型

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

1、全缓冲

在这种情况下,当填满标准I/O缓存后才进行实际I/O操作。全缓冲的典型代表是对磁盘文件的读写

2、行缓冲

在这种情况下,当在输入和输出中遇到换行符时,执行真正的I/O操作。这时,我们输入的字符先存放在缓冲区,等按下回车键换行时才进行实际的I/O操作。典型代表是键盘输入数据

3、不带缓冲

也就是不进行缓冲,标准出错情况stderr是典型代表,这使得出错信息可以直接尽快地显示出来

缓冲区的刷新

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

1、缓冲区时;

2、执行flush语句;(flush:冲洗,冲走)

3、执行endl语句;(end line)

4、关闭文件。

可见,缓冲区满或关闭文件时都会刷新缓冲区,进行真正的I/O操作。另外,在C++中,我们可以使用flush函数来刷新缓冲区(执行I/O操作并清空缓冲区),如:cout << flush; //将显存的内容立即输出到显示器上进行显示。刷新字面上的意思是用刷子刷,把原来旧的东西变新了,这里就是改变的意思,例如像缓冲区溢出的时候,多余出来的数据会直接将之前的数据覆盖,这样缓冲区里的数据就发生了改变。

endl控制符的作用是将光标移动到输出设备中下一行开头处,并且清空缓冲区

cout < < endl;

相当于

cout < < ”\n”< < flush;

通过实例演示说明

1、文件操作演示全缓冲

创建一个控制台工程,输入如下代码:

#include<fstream>
using namespace std;
 
int main()
 
{
    //创建文件test.txt并打开
    ofstream outfile("test.txt");
    //向test.txt文件中写入4096个字符’a’
    for(int n=0;n< 4096;n++)
    {
        outfile << 'a';
    }
    //暂停,按任意键继续
    system("PAUSE");
    //继续向test.txt文件中写入字符’b’,也就是说,第4097个字符是’b’
    outfile << 'b';
    //暂停,按任意键继续
    system("PAUSE");
    return 0;
}

上面这段代码很容易理解,已经在代码内部作了注释。

编写这段小代码的目的是验证WindowsXP下全缓冲的大小是4096个字节,并验证缓冲区满后会刷新缓冲区,执行真正的I/O操作。

编译并执行,运行结果如下:

此时打开工程所在文件夹下的test.txt文件,您会发现该文件是空的,这说明4096个字符“a”还在缓冲区,并没有真正执行I/O操作。敲一下回车键,窗口变为如下:

此时再打开test.txt文件,您就会发下该文件中已经有了4096个字符“a”。这说明全缓冲区的大小是4K(4096),缓冲区满后执行了I/O操作,而字符“b”还在缓冲区。
再次敲一下回车键,窗口变为如下:

此时再打开test.txt文件,您就会发现字符“b”也在其中了。这一步验证了文件关闭时刷新了缓冲区。

2、键盘操作演示行缓冲

先介绍getchar()函数。

函数原型:int getchar(void);

说明:当程序调用getchar()函数时,程序就等着用户按键,用户输入的字符被存放在键盘缓冲区中,直到用户按回车为止(回车字符也放在缓冲区中)。当用户键入回车之后,getchar()函数才开始从键盘缓冲区中每次读入一个字符。也就是说,后续的getchar()函数调用(有多少个字符就有多少次调用)不会等待用户按键,而直接读取缓冲区中的字符,直到缓冲区中的字符读完后,才重新等待用户按键。

不知道您明白了没有,再通俗一点讲,当程序调用getchar()函数时,程序就等着用户按键,并等用户按下回车键返回。期间按下的字符存放在缓冲区,第一个字符作为函数返回值。继续调用getchar()函数,将不再等用户按键,而是返回您刚才输入的第2个字符;继续调用,返回第3个字符,直到缓冲区中的字符读完后,才等待用户按键。

如果您还没有明白,只能怨我表达能力有限,您可以结合以下实例体会。

创建一个控制台工程,输入如下代码:

#include <iostream>
using namespace std;

int main()
{
    char c;
    //第一次调用getchar()函数
    //程序执行时,您可以输入一串字符并按下回车键,按下回车键后该函数才返回
    c=getchar();
    //显示getchar()函数的返回值
    cout << c << endl;
    //暂停
    system("PAUSE");
    //循环多次调用getchar()函数
    //将每次调用getchar()函数的返回值显示出来
    //直到遇到回车符才结束
    while((c=getchar())!='\n')
    {
        printf("%c",c);
    }
    //暂停
    system("PAUSE");
    return 0;
}

这段小代码也很简单,同样在代码内部都有注释。

getchar()函数的执行就是采用了行缓冲。第一次调用getchar()函数,会让程序使用者(用户)输入一行字符并直至按下回车键 函数才返回。此时用户输入的字符和回车符都存放在行缓冲区。

再次调用getchar()函数,会逐步输出行缓冲区的内容。

好了,本人表达能力有限,还是编译运行程序,通过运行结果自己领会吧。

编译运行程序,会提示您输入字符,您可以交替按下一些字符,如下:

您一直按下去,您就会发现当您按到第4094个字符时,不允许您继续输入字符。这说明行缓冲区的大小也是4K。

此时您按下回车键,返回第一个字符’a’,如下图:

继续敲一下回车键,将缓冲区的其它的字符全部输出,如下图:

 

3、标准错误输出不带缓冲

如错误输出时使用:

cerr<<”错误,请检查输入的参数!”;

这条语句等效于:

fprintf(stderr, ”错误,请检查输入的参数!”);

缓存(cache)

cache是一个非常大的概念。

一、CPU的Cache

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

二、磁盘的Cache

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

三、浏览器的Cache

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

四、Cache的大小

同样cache也有大小,例如现在市面上购买的CPU的cache越大,级数越多,CPU的访问速度越快。cache在很多方面都有应用,就不一一列举了。

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

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

Cache的核心作用是加快取用的速度(加快读取速度,包括CPU读内存、内存读磁盘、用户通过浏览器请求资源)比如你一个很复杂的计算做完了,下次还要用结果,就把结果放手边一个好拿的地方存着,下次不用再算了。加快了数据取用的速度。

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

有时候大家要好好理解这些专有名词字面上的意思,对理解这些概念有好处,缓冲:缓解冲击,缓存:临时存储

转自:https://www.cnblogs.com/duanwandao/p/9790325.html

  • 223
    点赞
  • 766
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
### 回答1: Linux中的buffer cache内存是指用于缓存磁盘数据的一块内存区域。当应用程序需要读取磁盘上的数据时,操作系统会将数据读入buffer cache中,以便下次读取时可以直接从内存中获取,避免频繁的磁盘访问,提高系统性能。同时,当应用程序需要写入数据时,操作系统也会将数据写入buffer cache中,然后再异步地将数据写入磁盘,以提高写入效率。buffer cache内存的大小可以通过系统参数进行配置,一般情况下会根据系统的内存大小和磁盘访问情况进行调整。 ### 回答2: 在Linux操作系统中,buffer cache缓冲区高速缓存)是用来提高文件系统性能的一种机制,是内核将经常访问的数据缓存在内存中的一部分。它的主要作用是降低磁盘I/O操作的延迟,提高文件系统的读取和写入速度。 Buffer cache是由内核维护的一块内存区域,它存储了最近被读取或写入的文件块数据。当应用程序需要读取文件时,内核会首先查找buffer cache,如果要读取的文件块在cache中,则直接从cache中读取数据,避免了磁盘I/O操作。如果要写入数据到文件,内核会将数据写入buffer cache,并在适当的时机将数据同步到磁盘上。 buffer cache的大小是动态调整的,根据系统的负载和需求进行自动调整。内核会根据当前系统内存的可用情况和其它进程的需求来判断是否需要释放部分buffer cache内存。如果系统内存紧张,内核会减少buffer cache的大小,以释放内存供其它进程使用;如果系统内存较为充足,内核会增加buffer cache的大小,以提高文件系统的性能。 使用buffer cache可以大幅提高文件系统的性能,尤其是对于频繁的读取和写入操作。通过将经常访问的数据缓存在内存中,可以减少对磁盘的访问次数,大大降低了I/O延迟带来的性能损耗。同时,缓存在内存中的数据可以更快地供应给应用程序,提高了文件系统的响应速度。 总之,buffer cache是Linux操作系统中的一种内存机制,用来提高文件系统的性能。它通过将经常访问的数据缓存在内存中,减少磁盘I/O操作,提高文件系统的读取和写入速度。同时,buffer cache的大小会根据系统的负载和需求进行动态调整,以确保系统的内存使用和性能的平衡。 ### 回答3: 在Linux操作系统中,buffer cache是一种磁盘I/O缓存机制,用于提高文件系统的访问性能。 当应用程序读取文件时,操作系统将文件的内容从磁盘读取到内存中的buffer cache中。如果下次再次读取同样的文件内容,操作系统可以直接从buffer cache中读取,而不需要再次去磁盘中访问。这样可以显著减少磁盘I/O操作,提高读取文件的速度。 类似地,当应用程序对文件进行写入时,数据首先被写入到buffer cache中,然后操作系统可以根据需要决定何时将数据刷新到磁盘中。这样可以将多个小的写入操作合并为一个大的写入操作,减少了磁盘I/O的负担,并提高了写入文件的效率。 Buffer cache内存的大小是动态分配的,它根据系统的需要自动增加或减少。当文件系统需要更多的内存时,它会从系统中获取一部分内存作为buffer cache,用于缓存更多的文件内容。当内存不足时,buffer cache会释放一部分内存,以便为其他系统组件提供更多的内存。 使用buffer cache机制可以显著提高文件系统的性能,比如读取和写入文件的速度。然而,buffer cache的使用也存在一些风险,比如在系统发生意外关机的情况下,尚未被写入磁盘的数据将会丢失。因此,在使用buffer cache时需要注意数据的持久性与一致性的问题,确保数据的安全性。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值