浅谈标准库I/O缓冲机制以及_exit和fflush函数的使用

文章详细介绍了标准库的I/O缓冲区的三种类型:全缓冲、行缓冲和无缓冲。全缓冲在缓冲区满时刷新,行缓冲遇到换行符或满时刷新,无缓冲则每次写操作都写入内核。_exit函数不刷新缓冲区直接退出,而exit会先刷新。fflush函数允许在需要时强制刷新缓冲区。程序示例用于验证这些行为。
摘要由CSDN通过智能技术生成

标准库的I/O缓冲区

  1. 全缓冲:如果缓冲区写满了就写回内核。常规文件通常是全缓冲的。
  2. 行缓冲:如果用户程序写的数据中有换行符就把这一行写回内核,或者如果缓冲区写满了就写回内核。标准输入和标准输出对应终端设备时通常时行缓冲的。
  3. 无缓冲:用户程序每次调库函数做写操作都要通过系统调用写回内核。标准错误输出通常是无缓冲的,这样用户程序产生的错误信息可以尽快输出到设备。

何时会刷新缓冲区?

  1. 缓冲区满时,自动刷新缓冲区
  2. 调用exit()函数退出程序
  3. 函数return时
  4. 调用fclose函数时
  5. 调用fflush函数时
  6. 对于行缓冲,遇到“\n”时,比如终端输入时

缓冲区大小

行缓冲为1024byte,全缓冲为4096byte。

验证程序:

#include <stdio.h>
#include <string.h>
#include <unistd.h>
int main(int argc,char *argv[]){
	char teststr[1030];
	int i;
	for(i=0;i<1030;i++){
		teststr[i]='a';
	}
	FILE *fp;
	fp=fopen(argv[1],"w");
	fwrite(teststr,1,sizeof(teststr),fp);
	_exit(-1);
}

该程序最终在test文件内输出1024个‘a’,即写满缓冲区后自动刷新。剩余6个a因为_exit()函数强制退出不刷新缓冲区所以并未输出成功。

_exit&exit

  1. _exit直接结束程序进入内核
  2. exit将缓冲区刷新再退出程序

_exit不刷新缓冲区验证程序:

#include <stdio.h>
#include <unistd.h>
 
int main(void) { 
	printf("hello\n");
	printf("world");
	_exit(0);
}

最终只输出hello,因为行缓冲遇到换行符刷新缓冲区,而没有输出world是因为_exit直接退出,并没有刷新缓冲区。

exit刷新缓冲区验证程序:

#include<stdio.h>
#include<stdlib.h>

int main(void) { 
	printf("hello\n");
	printf("world");
	exit(0);
}

最终输出hello和world。证明了exit函数退出时刷新缓冲区。

fflush函数

使用fflush函数,在未写满缓冲区的时候也可以写回内核,刷新缓冲区。

#include <stdio.h>

int fflush(FILE *stream);

我们这里引用man手册中对fflush函数的说明:

For output streams, fflush() forces a write of all user-space buffered data for the given output or update stream via the stream’s underlying write function.
For input streams associated with seekable files (e.g., disk files, but not pipes or terminals), fflush() discards any buffered data that has been fetched from the underlying file, but has not been consumed by the application.
The open status of the stream is unaffected.
If the stream argument is NULL, fflush() flushes all open output streams.
For a nonlocking counterpart, see unlocked_stdio(3).

使用例子:

#include <stdio.h>
#include <string.h>
#include <unistd.h>
int main(int argc,char *argv[]){
	char teststr[1030];
	int i;
	for(i=0;i<1030;i++){
		teststr[i]='a';
	}
	FILE *fp;
	fp=fopen(argv[1],"w");
	fwrite(teststr,1,sizeof(teststr),fp);
	fflush(NULL);
    _exit(-1);
}

最终输出1030个‘a’因为fflush强制刷新缓冲区。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值