0
点赞
收藏
分享

微信扫一扫

【Linux】库函数的缓冲区

追梦人的自留地 2022-05-04 阅读 73
c语言linux

缓冲区类型

  1. 全缓冲区:填满整个缓冲区后才执行系统调用操作,对于磁盘文件的操作通常使用全缓冲模式。全缓冲模式中的数据不会立即刷新,而是在缓冲区满了之后才会刷新。
  2. 行缓存区:当在输入和输出中遇到换行符时执行系统调用操作。当所操作的流涉及一个终端时(例如标准输入与标准输出),使用行缓冲模式。由于缓冲区长度是固定的,只要填满了缓冲区,即使还没有遇到换行符,也会刷新缓冲区。
  3. 无缓冲区:不进行缓存,直接执行系统调用操作。标准出错流stderr通常是不带缓冲区的,这使得出错信息能够尽快地显示出来。

示例

以下讨论的是用户级缓冲区。一般C库函数写入普通磁盘文件时,使用全缓冲模式,写入终端(例如标准输入与标准输出)时,使用行缓冲模式。printf和fwrite是属于C库函数,是自带缓冲区的,当他们的输出被重定向到普通磁盘文件时,数据的缓冲区由行缓冲变为全缓冲。全缓冲模式中的数据不会立即刷新,依旧存放在缓冲区中。但是执行fork函数之后,创建了子进程,子进程会拷贝父进程缓冲区中的数据。进程退出后,刷新所有缓冲区,父子进程分别打印出一份数据,于是有了两份数据。值得注意的是,系统调用write没有变化,说明系统调用不存在缓冲区。

#include <stdio.h>
#include <string.h>

int main()
{
 	const char *msg0 = "hello printf\n";
 	const char *msg1 = "hello fwrite\n";
	const char *msg2 = "hello write\n";
	 
	printf("%s", msg0);
	fwrite(msg1, strlen(msg0), 1, stdout);
	write(1, msg2, strlen(msg2));
	
	fork();
 	return 0;
}

输出到终端设备的结果如下:

[root@iZ2ze5eib0jy8qr762bqijZ temp]# gcc test.c -o test
[root@iZ2ze5eib0jy8qr762bqijZ temp]# ./test

在这里插入图片描述
输出重定向到磁盘文件的结果如下:

[root@iZ2ze5eib0jy8qr762bqijZ temp]# ./test > file
[root@iZ2ze5eib0jy8qr762bqijZ temp]# cat file

在这里插入图片描述

使用库函数的优点

  • 系统调用与操作系统有关,而库函数会根据当前的操作系统调用对应的底层函数,但提供的接口不变,因此可移植性好。
  • 库函数的缓冲机制减少了系统调用次数,即减少了用户态与内核态之间的转换,提升系统性能。
举报

相关推荐

0 条评论