首页 > 解决方案 > 为什么这段代码有时只调用 printf() 一次而不是两次?

问题描述

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

int main() {
    
    pid_t pid;
    pid = fork();

    fork();
    if (pid > 0) {
        printf("Hello, World!\n");
    }

    return EXIT_SUCCESS;
}

当上面的代码运行时,它会打印以下输出,这是预期的:

Hello, World!
Hello, World!

但有时我再次执行代码后会得到以下输出:

Hello, World!

为什么代码有时只打印一次消息?

这只发生在程序在 IDE 的终端或类似 onlinegdb 的环境中运行时。

当程序从交互式 shell 启动时,​​是会出现“Hello, World!”这两个预期行。被打印。

标签: cprocessforkpid

解决方案


TL; DR 分叉孩子和退出之间的竞争条件

根据子级或父级在(第二个)分叉之后是先运行,父级可以打印消息并退出,IDE 可以检测到它已退出并在子级运行之前关闭所有内容,并且打印它的消息。

从 bash 运行时不会发生这种情况,因为即使发生这种情况,孩子仍然能够输出它的消息。理论上,这可能会在 shell 打印下一个提示符后发生,但这似乎极不可能。

要记住的重要一点是,您的程序总是由某些东西(shell 或和 IDE 或其他)运行,并且某些东西会等待它退出,但不会等待您可能分叉的任何孩子。因此,如果您想确保您的孩子完成,您需要在退出之前等待他们。


推荐阅读