这段代码C可能的3个输出是什么?叉子()

时间:2015-06-23 17:59:13

标签: c fork

我是这个fork语句的新手,我不知道在c程序上的fork方法。你能告诉我这段代码的三个可能输出是什么..

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

int main(void) {
    printf("10\n");
    if (fork())
        printf("2\n");
    else
        printf("3\n");
    printf("4\n");
    return 0;
}

我只知道它的一个输出是

10
3
4

if (fork())为真时,其他2个输出是什么?

2 个答案:

答案 0 :(得分:3)

理解它的关键很简单:fork(),如果成功,则返回两次:在父级和子级中。在父母中,它返回新生儿的PID;在孩子中它返回0;

10 3 4永远不会发生:如果打印3,则表示已成功创建子进程(因为fork()在子级上返回0),因此有两个进程将打印4。假设fork()成功,输出中只有一个4是不可能的。

以下是可能的输出集:

  • 10 2 4 3 4:如果父级首先执行所有内容,然后是子级,则会发生这种情况。父母打印10 2 4,然后孩子打印3 4
  • 10 2 3 4 4:当父项首先执行,打印2,然后子项执行并打印3,然后父项或子项打印4时发生,然后另一个打印4
  • 10 3 4 2 4:在孩子首先执行,打印34时发生,然后父母恢复并打印24
  • 10 3 2 4 4:当孩子先执行,打印3,然后父母恢复并打印2,然后父母或孩子打印4时,就会发生,然后另一个打印最终的4
  • 10 2 4:当fork()失败并返回-1时发生,在这种情况下,没有创建子项,因此您只获得原始流程的输出

如果您在行缓冲终端中运行程序,这些都是可能的。但是,如果您将输出重定向到某个文件,您可能会惊讶地看到输出中的10不止一次。

这是因为重定向到文件通常会将缓冲模式从行缓冲切换为完全缓冲。假设缓冲区大小大于字符串10\n的3个字符,并且缓冲区在此期间没有刷新 - 也是一个合理的假设 - 孩子将从包含{{1的输出缓冲区开始}}。所以,你最终在输出中有两个10\n

因此,在这种情况下,可以扩展一组可能的输出,以便在孩子打印10\n之前的每种可能性中包含另一个10

  • 3
  • 10 2 4 10 3 4
  • 10 2 10 3 4 4
  • 10 10 3 4 2 4

答案 1 :(得分:2)

程序应输出以下内容之一:

10 2 3 4 4
10 2 4 3 4
10 3 4 2 4
10 3 2 4 4

由于fork()返回两次,一次为父,一次为子,一次由父打印一次,父打印2和4,客户打印3和4.

由于父和子都打印到同一个控制台,并且两个进程之间没有明确的语句排序,实际上有六个可能的输出,其中四个是不同的。