目录
简介:C库三种缓存模式,行缓存、全缓存、无缓存,你认为库函数的缓存方式是怎么样的,这篇文章通过几个函数来论证一下。
1 缓存的概念
1.程序中的缓存,位于用户空间----用户空间的缓存
2.每打开一个文件,内核在内核空间中也会开辟一块缓存,这个叫内核空间的缓存
文件IO中的写即是将用户空间中的缓存写到内核空间的缓存中。
文件IO中的读即是将内核空间的缓存写到用户空间中的缓存中。
3.标准IO的库函数中也有一个缓存,这个缓存称为----库缓存
C库缓存的特点:
1.遇到\n 时,会将库缓存的内容写到内核缓存中,即调用了系统调用函数。
2.库缓存写满时,会调用系统调用函数,将库缓存内容写到内核缓存中,***长度为1024字节***。
#include <stdio.h>
int main()
{
printf("hello world");
while(1); //让程序一直在此,程序结束也会将缓存中的数据写入到内存或者磁盘中。
return 0;
}
图七
1.2 行缓存
遇到\n,或者写满缓存时,调用系统调用函数与内核交互。
写:puts,putchar,printf
读:getchar
1.3全缓存(块缓存)
只有写满缓存,或者fflush强制刷新缓存,才调用系统调用函数。
1.4无缓存
输出错误信息:stderr
stderr和stdout虽说都能在终端输出,但两个是不同的输出流。
2.函数的缓存方式
根据下面例子的验证,函数的缓存方式没有限制,函数的缓存方式是根据文件的缓存机制确定的,向终端中输入或输出为行缓存,普通文件输入读出为全缓存(除printf,putchar,puts,getchar···默认输出到终端,因为输出到终端的原因所以为行缓存,其实标准输入输出的缓存模式也可以通过setbuf函数改变)。
2.1 fputc函数论证
2.1.1 标准输出默认缓存方式
#include <stdio.h>
int main()
{
fputc('x', stdout);
//fputc('\n', stdout); 验证行缓存
while(1);
return 0;
}
终端输出
2.1.2 自定义缓存方式
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char **argv) //argc:终端输入参数的个数,如./a.out test.txt, argv = 2;
//argv: 输入的参数字符串数组,如./a.out test.txt,
//argv[1]=./a.out, argv[2]=test.txt
{
if(argc<2)
{
printf("input para less than 2\n");
exit(1);
}
FILE* fp;
int nRet = 0;
char buf[8000];
setbuf(stdout, buf); //改变标准输出的缓存方式为全缓存。
fp = fopen(argv[1], "r");
if(fp == NULL)
{
perror("fopen");
exit(1);
}
while(1)
{
nRet = fgetc(fp);
if(!feof(fp)) break;
fputc(nRet, stdout);
}
//fflush(fp); 刷新缓存,判断全缓存
while(1);
fclose(fp);
return 0;
}
终端输出
2.2 fwrite函数论证
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
int main()
{
FILE* fp;
int nRet = 0;
int count =0;
char buf[] = "hello world\n";
//char fullbuf[2000];
//setbuf(stdout, fullbuf); //change the cache mode of stdout
if(fwrite(buf, strlen(buf), 1,stdout)<1)
{
perror("fwrite");
exit(1);
}
while(1);
fclose(fp);
return 0;
}
2.2.1 标准输出默认缓存方式
2.2.2 自定义缓存方式
上面的文件取消这两条注释即可
char fullbuf[2000];
setbuf(stdout, fullbuf); //change the cache mode of stdout
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
int main()
{
FILE* fp;
int nRet = 0;
int count =0;
char buf[] = "hello world\n";
char fullbuf[2000];
setbuf(stdout, fullbuf); //change the cache mode of stdout
if(fwrite(buf, strlen(buf), 1,stdout)<1)
{
perror("fwrite");
exit(1);
}
while(1);
fclose(fp);
return 0;
}
终端输出