【问题标题】:C fork program explanationC fork 程序说明
【发布时间】:2017-11-02 07:06:28
【问题描述】:

我有如下代码

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>

int main(int argc, char *argv[])
{
    printf("a\n");
    fork();

    printf("b\n");
    if(fork() == 0) {
        printf("c\n");
        exit(0);    
    }
    printf("d\n");
    return 0;
}

输出:

a
b
d
a
b
c
a
b
d
a
b
c

我不知道为什么输出重复了很多次。

【问题讨论】:

  • 您是否将输出重定向到文件?
  • 你调用了两次fork,第一次你甚至不关心它的结果(但你应该,而且你需要处理它的失败)
  • 在您的printf 中使用getpid(2),例如printf("a from pid %d\n", (int)getpid());
  • 运行此程序的方式和位置很重要。你也应该说明预期的输出

标签: c fork stdio


【解决方案1】:

不知道为什么输出重复了很多次

因为printf() 被缓冲了。

当一个进程调用fork() 时,生成的子进程会获得父进程输出缓冲区的副本。

您可以通过在每次调用 fork() 之前放置 fflush(stdout) 来清空此输出缓冲区。在这种情况下,输出应该是:

a
b
b
d
c
d
c

请注意,如果输出指向终端,默认情况下它将是行缓冲,即:每次将\n 发送到输出时都会转储缓冲区。如果您将输出重定向到文件,则不是这样。

【讨论】:

  • 错了。缓冲说明了顺序,但没有说明输出的数量。
  • @BasileStarynkevitch 的缓冲解释了为什么a 显示不止一次,以及为什么b 显示四次而不是两次。
  • "每次发送一个 \n 到输出时都会转储缓冲区" --- 如果在每个 \n 之后刷新它,为什么那里有 4 个 as?
  • 不,缓冲没有解释这一点。 a 被多次打印的事实是由于 fork 的行为(而不是 printf)。
  • @zerkms 我的意思是:如果输出指的是终端,那么它是 line-buffered 默认情况下:可以更改默认行为.
【解决方案2】:

当您调用fork() 时,它会获取调用进程的输出缓冲区的副本。默认情况下启用缓冲,因此您会得到此行为。 你可以使用

fflush(stdout);

在调用 fork() 之前。或者,您也可以使用

禁用缓冲
setbuf(stdout, NULL);

您可以阅读更多关于 fork here 的信息。如果您需要更多帮助,请告诉我。

【讨论】:

    【解决方案3】:

    答案已经在 cmets 中了。你打电话给fork() 两次。所以解决方案是只调用一次并将结果保存在像int pid = fork() 这样的变量中。此外,您应该检查 fork-call 是否失败(如果失败,则返回负值)。

    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/types.h>
    #include <unistd.h>
    
    int main(int argc, char *argv[])
    {
        printf("a\n");
    
        int pid = fork();
        if (pid < 0)
        {
            fprintf(stderr, "Can't fork!");
            exit(1);
        }
    
        printf("b\n");
    
        if(pid == 0)
        {
            printf("c\n");
        }
        else
        {
            printf("d\n");
        }
    
        return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 2023-03-07
      • 1970-01-01
      • 2021-05-06
      • 1970-01-01
      • 2019-03-12
      • 2018-01-01
      • 2017-09-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多