printf打印有无‘\n’的理解和其在fork中的一点注意

printff函数也是标准输出函数,向STDOUT_FILENO(标准输出)输出。标准io是带缓冲机制的全缓冲

标准IO的缓冲机制:

全缓冲 写满缓冲(EOF),主动冲刷flush(),数据才执行io操作(一般文件)

行缓冲 一行数据遇到“\n”,才执行io操作(一般终端)

无缓冲   立即输出到文件或终端,如fput(),write()       

#include <stdio.h>
#include <unistd.h>
int main()
{

    printf("hello,world");

    sleep(3);
    return 0;
}
/*
hello,world不会先在终端(标准输出)打印,原因是printf与终端交互,是行缓冲的,
遇到“\n”才会立即冲刷缓冲区(立即打印到终端),
所以不会直接打印到屏幕,
后来程序结束,内核会来将缓冲区清空(冲刷),
所以最后打印hello,world。
*/
#include <stdio.h>
#include <unistd.h>
int main()
{

    printf("hello,world\n");

    sleep(3);
    return 0;
}
/*
在这里增加了"\n",printf函数还是行缓冲的,
遇到'\n'就立即输出到屏幕,此时缓冲区是没有数据了,这也很重要
所以你会看到屏幕先有hello,world打印,睡眠3秒再结束。
*/

测试:

第一种:

刚开始执行时

3秒后:

程序结束,内核清理

第二种:

 

 3秒后程序结束

 ------------------------------------------------------------------------以上是printf为行缓冲时的相关问题。

unix高级环境编程有一句话:如果标准输出连接到终端设备,则他是行缓冲的,否则他是全缓冲的。(184页---介绍fork函数时)

#include <stdio.h>
#include <unistd.h>

char *p="I have apples\n";

int main()
{
    pid_t pid;

    if( write(STDOUT_FILENO,p,14)!=14 )
        perror("write:\n");

    printf("before fork");

    if( (pid = fork())<0 ) perror("fork error\n");
    else if( pid==0 )
    {
        printf("I am chlid\n");
    }
    else
    {
        sleep(1);
        printf("I am parent\n");
    }
    return 0;
}

/*
结合了fork和write,先看write函数,不带缓冲,可以直接将p所指向的数据打印到屏幕,
打印的before fork,此时是在缓存区里面,并没有在终端,
后面申请的fork函数,由于sleep让main进程睡眠,后执行了,
所以先执行子进程的工作,
此时子进程拷贝的缓冲区含义已经before fork了,
所以子进程最终打印的形式为:before fork I am chlid
(为什么before...先打印,该缓冲区相当于一个队列,先进先出(可以这样理解吧))
*/
/*
将before fork后加上“\n”,子进程将不会打印"before fork"语句,
原因是‘\n’冲刷了缓冲区,子进程拷贝了已经没有数据的缓冲区了,所以子进程不会打印before fork.
*/

 测试:

没有‘\n’:

 有‘\n’时:

 ------------------------------------------------------------------------------------------以上是printf与全缓存区的联系

还有一种就是将命令行输出通过重定向到一个文件:有无”\n“文件中的数据都和没有‘\n’时一样

都会出现两次before fork。

 原因:由于重定向到 文件,printf缓冲区变成了全缓冲的了,不会因为'\n'而冲刷缓冲区(只有写满或程序结束时冲刷)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值