内存缓冲区解析
Posted lovejobs
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了内存缓冲区解析相关的知识,希望对你有一定的参考价值。
一.缓冲区顾名思义即为:内存中开辟的一片缓冲区域
按类型分为:全缓冲,行缓冲,不带缓冲
可以通过标准库函数setvbuf(_Inout_ FILE * _File, _Inout_updates_opt_z_(_Size) char * _Buf, _In_ int _Mode, _In_ size_t _Size);来设置缓冲区的类型
1.全缓冲:
当当填满标准IO的缓存后才进行实际IO操作。
windows和linux都可以通过给_Mode设为_IOFBF设置全缓冲。
全缓冲的典型就是对磁盘文件的读写。
缓冲区为空,一次读满数据,再写出。
windows下测试代码1:
1 void main() 2 { 3 char buf[1024];//缓冲区大小为1024 4 setvbuf(stdout, buf, _IOFBF, 1024); 5 printf("中国女排很给力!\\n\\n"); 6 //while (1) 7 //{ 8 // printf("hello"); 9 10 // Sleep(10); 11 //} 12 //setvbuf(stdout, NULL, _IONBF, 0); 13 system("pause"); 14 }
结果:不会输出
测试代码2:
1 void main() 2 { 3 char buf[1024];//缓冲区大小为1024 4 setvbuf(stdout, buf, _IOFBF, 1024); 5 printf("中国女排很给力!\\n\\n"); 6 while (1) 7 { 8 printf("hello"); 9 10 Sleep(10); 11 } 12 //setvbuf(stdout, NULL, _IONBF, 0); 13 system("pause"); 14 }
结果:
2.行缓冲:
在输入输出遇到换行符时,执行真正的IO操作。
linux输出默认是行缓冲,以回车结束。windows没有行缓冲,不能设置,一旦设置变为全缓冲。
设置行缓冲为:_IOLBF
这时候输入的字符先存放至缓冲区,等按下回车键时才进行实际IO操作。
典型代表就是键盘输入数据,每次读取一行。
windows下测试代码1:
1 void main() 2 { 3 char buf[4096]; 4 setvbuf(stdout, buf, _IOLBF, 4096); 5 printf("中国女排很给力!"); 6 //while (1) 7 //{ 8 // printf("hello"); 9 //} 10 //setvbuf(stdout, NULL, _IONBF, 0); 11 system("pause"); 12 }
测试结果:不会直接打印出来,会输入缓冲区
windows下测试代码2:
1 void main() 2 { 3 char buf[4096]; 4 setvbuf(stdout, buf, _IOLBF, 4096); 5 printf("中国女排很给力!\\n\\n"); 6 //while (1) 7 //{ 8 // printf("hello"); 9 //} 10 //setvbuf(stdout, NULL, _IONBF, 0); 11 system("pause"); 12 }
测试结果:可以看出设置行缓冲就是设置全缓冲,遇到换行符也不会输出。
windows下测试代码3:
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<windows.h> 4 5 void main() 6 { 7 char buf[1024];//缓冲区大小为1024 8 setvbuf(stdout, buf, _IOLBF, 1024); 9 printf("中国女排很给力!\\n\\n"); 10 while (1) 11 { 12 printf("hello"); 13 14 Sleep(10); 15 } 16 setvbuf(stdout, NULL, _IONBF, 0); 17 system("pause"); 18 }
测试结果:等缓冲区满后才一次性输出
3.不带缓冲区:
直接进行实际的输入输出操作。
windows默认输出不带缓冲,linux可以设置setvbuf(stdout, NULL, _IONBF, 0);而不带缓冲
典型代表是标准错误stderr,这样可以使错误信息尽快显示出来
windows默认输出测试代码:
#include<stdio.h> #include<stdlib.h> void main() { printf("中国女排很给力!"); //setvbuf(stdout, NULL, _IONBF, 0); system("pause"); }
结果:直接输出,不带缓冲区。
4.缓冲区的刷新
--所谓刷新对输出而言是将缓冲区内容立即输出
windows测试代码:
1 void main() 2 { 3 char buf[1024];//缓冲区大小为1024 4 setvbuf(stdout, buf, _IOFBF, 1024); 5 printf("中国女排很给力!"); 6 fflush(stdout);//刷新屏幕输出缓冲区,使缓冲区的内容输出 7 //while (1) 8 //{ 9 // printf("hello"); 10 11 // Sleep(10); 12 //} 13 //setvbuf(stdout, NULL, _IONBF, 0); 14 system("pause"); 15 }
测试结果:对于满缓冲输出模式,可以立即输出缓存内容
--对输入而言是刷新后面的内容被抛弃
测试代码:
1 void main() 2 { 3 char c = getchar(); 4 printf("%c\\n", c); 5 c = getchar(); 6 printf("%c\\n", c); 7 fflush(stdin);//刷新屏幕输出缓冲区,使缓冲区的内容输出 8 c = getchar(); 9 printf("%c\\n", c); 10 c = getchar(); 11 printf("%c\\n", c); 12 13 system("pause"); 14 }
测试结果:可以看到fflush后面的输入被丢掉了
以上是关于内存缓冲区解析的主要内容,如果未能解决你的问题,请参考以下文章
原创mysql内核源代码深度解析 缓冲池 buffer pool 整体概述
[Go] 通过 17 个简短代码片段,切底弄懂 channel 基础
java缓冲字符字节输入输出流:java.io.BufferedReaderjava.io.BufferedWriterjava.io.BufferedInputStreamjava.io.(代码片段