glibc的头文件 linux_linux下C标准库glibc的缓存机制

C库函数提供三种缓冲机制,分别是下图中的unbuffered无缓存、block buffered块缓存(也称全缓存,会把缓存块写满,然后一次性刷入磁盘)和line buffered行缓存。 在man setbuffer中可以看到三种缓存的说明;

下面是各种缓存的中文说明

C库并提供了三种函数修改缓存,可见man setbuffer

前三个函数是最后一个声明setvbuf的封装,在man手册中有说明。

The setbuf() function is exactly equivalent to the call

setvbuf(stream, buf, buf ? _IOFBF : _IONBF, BUFSIZ);

Thesetbuffer()functionisthesame,except that the size of the buffer is up to the caller,

rather than being determined by the default BUFSIZ.

the setlinebuf() function isexactlyequivalent to the call:

setvbuf(stream, NULL, _IOLBF, 0);

Setvbuf中的形参but表示自定义的缓冲区,如果为NULL,会由c库自行分配。如果不为NULL,第4个参数size则为缓冲区大小。第三个参数mode是指缓冲区类型,_IONBF指io no buffer即无缓存, _IOLBF指line行缓存,_IOFBF指full全缓存 。

下面是原文

测试一下行缓存,查看以下代码:

会有怎样的输出呢?见下图:

为什么“father line 1 ”会被输出两次?原因是默认C运行库是使用行缓存,行缓存是直到遇到’ ’才将缓存内容刷到标准输出,否则会一直存着,直到缓冲区满了为止才刷新。

在第6行代码执行后,c库并未将输出结果立即刷到标准输出,因此还停留在缓冲区中。子进程会继承父进程的缓冲区,因此子进程缓存区中也包括了

“father line 1 ”。

原理清楚了,解决的方法必然是强制刷新缓存就行了,这可以用fflush函数来完成,fflush的声明及帮助如下:

注意,flush的参数类型是FILE*,我们必须传入相同参数类型,这是C库头文件/usr/include/stdio.h中定义的,

但是我们要将输出刷新到屏幕,即标准输出stdout,因此我们可以通过man stdout获得相应帮助,如下图所示:

这里声明的是extern,即外部的,那stdin在哪里呢?依然是在stdio.h中,如下图所示:

好,让我们加上fflush函数,代码如下 。

程序输出结果如下,符合预期:

再来一个方法,通过setbuf来搞定。

执行结果如下:

打完收工。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值