输出缓冲区

 

 
 
 
先来看以下一段代码(test.c):

  1 #include<stdio.h>
  2 #include<sys/types.h>
  3
  4 int main()
  5 {
  6     pid_t pid;
  7     fprintf(stdout,"%s","Start fork...");
  8     pid = fork();
  9     switch(pid)
 10     {
 11     case -1:
 12         break;
 13     case 0:
 14         printf("%s","Child process.\n");
 15         break;
 16     default:
 17         printf("%s","Parent process.\n");
 18         break;
 19     }
 20     return 0;
 21 }


编译执行:

$gcc -o test test.c
$./test
Start fork...Child process.
Start fork...Parent process.

   出乎意料的是,为什么"Start fork..."输出了两次呢?子进程是从fork之后的语句开始执行的,那么多出来那个"Start fork..."是哪里来的呢?

先了解一下缓冲区:

  这个缓冲区既不是内核中的缓冲区,也不是用户分配的缓冲区,而是有编译器维护的用户进程空间中的缓冲区.缓冲区类型有:全缓冲(大部分缓冲都是这类型)、行缓冲、无缓冲。

  标准里没有规定各种流是什么缓冲,stderr和stdout是哪种缓冲类型是和环境相关的。 stderr 可能是无缓冲、行缓冲,但不能是全缓冲。stdin 和 stdout 可能是无缓冲、行缓冲,也可能是全缓冲。不过,stdin 和 stdout 如果分别是指键盘和显示器等交互设备(interactive device)的话,那么只能是无缓冲或行缓冲。

  默认情况下,printf()在屏幕输出的时候是行缓冲的,所以父进程在执行了第一个printf语句后,"Start fork..."还保存在缓冲区中,执行fork的时候,父进程缓冲区的数据也被复制到子进程中,子进程在刷新缓冲区的时候,输出了从父进程复制来的"Start fork..."。
 
下面对程序进行一些修改:
1、如果把第7句改为:
fprintf(stdout,"%s","Start fork...\n");
$./test
Start fork...
Child process.
Parent process.
说明当前环境下printf是行缓冲的。

把修改过的程序的执行结果重定向到文件中:
$./test > temp
$cat temp
Start fork...
Child process.
Start fork...
Parent process.
这说明将printf输出结果重定向到文件的时候就变了全缓冲.

2、如果在第7行以后加入一句:
fflush
(stdout);

$./test > temp
$cat temp
Start fork...
Child process.
Parent process.
我们用fflush强制刷新缓冲区,这样父进程缓冲区被清空。我们在fork之前一般都要用fflush(NULL)清空所有流。

3、我们把第7句改为:
fprintf(stderr,"%s","Start fork...");
$./test > temp
Start fork...
$cat temp
Child process.
Parent process.

把修改过的程序的执行结果重定向到文件,把标准错误重定向到标准输出:
$./test > temp 2>&1
$cat temp
Start fork...
Child process.
Parent process.
表明当前环境stderr的默认目标是终端,而且是不缓冲的.

4、如果我们在第7句之前加入:
setvbuf
(stdout, NULL, _IONBF, 0);
设置标准输出为无缓冲。
$./test > temp
$cat temp
Start fork...
Child process.
Parent process.

 

转载于:https://www.cnblogs.com/kahreman/archive/2012/06/18/2553101.html

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值