我是这个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个输出是什么?
答案 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
:在孩子首先执行,打印3
和4
时发生,然后父母恢复并打印2
和4
。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.
由于父和子都打印到同一个控制台,并且两个进程之间没有明确的语句排序,实际上有六个可能的输出,其中四个是不同的。