【问题标题】:Difference in Output between printf("\n...") and printf("..\n") in Linux [duplicate]Linux 中 printf("\n...") 和 printf("..\n") 之间的输出差异 [重复]
【发布时间】:2018-08-12 06:11:49
【问题描述】:

有人可以向我解释为什么这两个相似的代码(\n 位置除外)会导致不同的输出:

#include <unistd.h>
#include <sys/wait.h>
#include <stdio.h>

int main()
{
    int pid, i=0;
    printf("Ready to fork\n");
    pid=fork();
    if (pid==0)
    {
        printf("Child starts\n");
        for (i=0; i<1000; i++);
        printf("Child ends\n");
    }
    else
    {
        wait(0);
        for (i=0; i<1000; i++);
        printf("Parent process ends\n");
    }
    return 1;
}

输出:

还有这个:

#include <unistd.h>
#include<sys/wait.h>
#include <stdio.h>

int main()
{
    int pid, i=0;
    printf("\nReady to fork %d", getpid());
    pid=fork();
    if (pid==0)
    {
        printf("\nChild starts %d",getpid());
        for (i=0; i<1000; i++);
        printf("\nChild ends %d", getpid());
    }
    else
    {
        wait(0);
        for (i=0; i<1000; i++);
        printf("\nParent process ends %d", getpid());
    }
    return 1;
}

结果:

我真的找不到任何令人满意的理由来解释为什么 \n 的位置的简单更改会在 fork 执行完成后父程序似乎重新启动的级别更改程序的输出。

提前谢谢你。

【问题讨论】:

  • 您可以格式化您的代码,以便其他人阅读。而且,'\n' 通常位于末尾。输出没有变化。
  • @IharobAlAsimi:输出没有变化是什么意思?整个问题询问为什么输出有变化。它显示了改变的输出。
  • 我不会阅读那个未格式化的代码,但可能与fork() in c using printf重复
  • 现在看到了,只是一开始没注意。
  • @LưuVĩnhPhúc 是的,重复

标签: c linux printf


【解决方案1】:

除非程序的输出被重定向到一个文件,printf()ing \n 结果,默认情况下,在 刷新 用户空间缓冲区 printf()内部使用。

fork() 之前不刷新缓冲区意味着子进程获得了父进程尚未刷新缓冲区的副本。出于这个原因,您在未打印 \n 的版本中看到了两次 Ready to fork,因为在调用 fork() 之前执行了对 printf() 的调用以打印 Ready to fork

【讨论】:

  • 这就解释了。非常感谢。
  • 有点混乱......是孩子获取缓冲区数据,还是当控件返回调用者并找到“\n”时它会刷新缓冲区?
  • 子进程总是通过fork()ing 获得父缓冲区的副本。问题是:这个缓冲区是否为空?好吧,如果缓冲区在调用fork() 之前被刷新,它肯定是空的。通过使用尾随\n 调用printf() 来刷新缓冲区(除非重定向输出或更改刷新策略)。在您的第一种情况下,父母正在这样做。
  • 注意fork()之后的两个缓冲区(父子缓冲区)都是独立的(即:每个进程都有自己的副本),但它是在分叉的那一刻,子进程得到一个副本父级缓冲区(即:子级缓冲区在此时使用父级缓冲区的内容进行初始化)。
猜你喜欢
  • 2014-04-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-08-06
相关资源
最近更新 更多