缓冲区与setvbuf函数
缓冲区
该笔记适用于Ubuntu,在Windows或其他平台上可能会存在不同。
什么是缓冲
缓冲区又称为缓存,它是内存空间的一部分,用来缓冲输入或输出的数据。
为什么要引入缓冲区呢?
比如我们从磁盘里取信息,我们先把读出的数据放在缓冲区,计算机再直接从缓冲区缓冲区中取数据,等缓冲区的数据取完后再去磁盘中读取,这样就可以减少磁盘的读写次数,再加上计算机对缓冲区的操作远快于对磁盘的操作,故应用缓冲区可大大提高计算机的运行速度。
缓冲区就是一块内存区,它用在输入输出设备和CPU之间,用来缓存数据。它使得低速的输入输出设备和高速的CPU能够协调工作,避免低速的输入输出设备占用CPU,解放出CPU,使其能够高效率工作。
缓冲区的类型
缓冲区分为三种类型:全缓冲、行缓冲和不缓冲。
1、全缓冲
在这种情况下,当填满标准I/O缓存后才进行实际的I/O操作。全缓冲的典型代表是对磁盘文件的改写。
2、行输出
在这种情况下,当在输入和输出中遇到换行符时,执行真正的I/O操作。这时,我们输入的字符先存放在缓冲区,等按下回车键换行时才进行实际的I/O操作。典型的代表是键盘输入数据。
3、不缓冲
也就是不进行缓冲,标准出错情况stder是典型代表,这使得出错信息可以直接尽快地显示出来。
缓冲区的刷新
下列情况会引发缓冲区的刷新:
- 缓冲区满时;
- 执行fflush函数;
- 正常关闭文件;
- 正常退出程序或进程;
- 行缓冲遇到\n刷新。
如何改变缓存类型
这里只展示setvbuf函数的使用,定义流stream应如何缓冲。
1 | //与缓冲区相关的一些函数 |
模式 | 描述 |
---|---|
_IOFBF | 全缓冲:对于输出,数据在缓冲填满时被一次性写入。对于输入,缓冲会在请求输入且缓冲为空时被填充。 |
_IOLBF | 行缓冲:对于输出,数据在遇到换行符或者在缓冲填满时被写入,具体视情况而定。对于输入,缓冲会在请求输入且缓冲为空时被填充,直到遇到下一个换行符。 |
_IONBF | 无缓冲:不使用缓冲。每个 I/O 操作都被即时写入。buffer 和 size 参数被忽略,即在无缓存模式,即使设置了缓冲区也不会用到。 |
验证
先来对比VScode和Ubun中缓冲的表现形式
Vscode:
1.
2.
3.
4.
Ubuntu:
1.
2.
3.
4.
5.
6.
从以上10个测试可以得到结论:(不同平台不同的编译器得到的结果可能不一样)
- VScode中的stdout属于无缓冲类型
- Ubuntu中的stdout属于行缓冲类型(行缓冲遇到换行符会清空缓冲区,而全缓冲不会)
注意:缓冲区的大小选择1024(不管用默认的还是自己定义的)
验证setvbuf函数
- 当缓冲区满的时候会刷新缓冲区
当设为无缓冲区时,所设置的缓冲区会被忽略
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 TYsec!