(不)带缓存的I/O操作

文章目录

三种缓存类型


标准 I/O 库提供缓冲的目的就是尽可能的减少系统调用,从而提高 I/O 操作的效率。标准的 I/O 操作提供了三种类型的缓冲:全缓冲行缓冲不带缓冲

  • 全缓冲: 在填满标准 I/O 缓冲区后才进行实际的 I/O 操作;
    • 例如:对于驻留在磁盘上的文件,就是进行全缓冲操作;
    • 全缓冲可以由 I/O 自动冲洗;
    • 全缓冲也可以用 fflush 冲洗一个文件流;
  • 行缓冲: 在填满标准 I/O 缓冲区一行后才进行实际的 I/O 操作;
    • 当输入或输出中遇到换行符时,自动执行行缓冲操作;
    • 如果文件流涉及到终端设备,则它们是行缓冲;否则是全缓冲;
  • 不带缓冲: 对字符进行缓冲存储,即有一个字符操作就马上进行读写操作;
    • 例如,如果使用 fputs 写入 15 个字符到不带缓冲的流中,会调用系统函数write 15 次;
    • 标准出错流 stderr 通常是不带缓冲的;
  • 我们可以通过以下方式更改缓冲类型:
void setbuf(FILE *restrict_fp, char *restrict_buf);
int setvbuf(FILE *restrict_fp, char *restrict_buf, int mode, size_t size);

举个例子来说明:如果文件流涉及到终端设备,则它们是行缓冲;否则是全缓冲;代码如下:

// 文件名:file1.c
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>

int global = 4;

int main(void)
{
     pid_t pid;
     int vari = 5;
	
     printf("%s: %d: before fork\n", __FILE__, __LINE__);
	
     if((pid = fork()) < 0) {
          printf("%s: %d: fork error\n", __FILE__, __LINE__);
          exit(0);
     }
     else if(pid == 0) {
          global++;
          vari--;
          printf("%s: %d: Child changed\n", __FILE__, __LINE__);
     }
     else printf("%s: %d: Parent did not changed\n", __FILE__, __LINE__);
     printf("%s: %d: global = %d; vari = %d\n", __FILE__, __LINE__, global, vari);
     return 0;
}

默认输出到终端,应该是行缓冲:

$ gcc file1.c -o file1
$ ./file1 
file1.c: 13: before fork
file1.c: 24: Parent did not changed
file1.c: 26: global = 4; vari = 5
file1.c: 22: Child changed
file1.c: 26: global = 5; vari = 4

由上可知,file1.c: 13: before fork 只打印出了一行,标准输出是行缓冲,很快被新的一行冲掉了;


我们重定向输出到指定的文件,此时应该是全缓冲:

$ cat temp 
file1.c: 13: before fork
file1.c: 24: Parent did not changed
file1.c: 26: global = 4; vari = 5
file1.c: 13: before forl
file1.c: 22: Child changed
file1.c: 26: global = 5; vari = 4

由上可知,file1.c: 13: before fork 打印了两行;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值