2016-09-18 34 views
2

我在C程序,它利用fork()系统调用:现在ç叉程序输出的解释

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

void doit(void) 
{ 
    pid_t pid; 
    fork(); 
    fork(); 
    printf("Unix System Programming\n"); 
    return; 
} 

int main(void) 
{ 
    doit(); 
    printf("WTF\n"); 
    exit(0); 
} 

,这个节目给了我8行输出。我认为这是因为两叉2^2 = 4次* 2打印声明= 8次。如果我错了,请纠正我并解释原因。

现在,问题是为什么我在每次运行中获得不同的输出?比方说,我执行此代码:我第一次得到输出

Unix System Programming 
WTF 
Unix System Programming 
Unix System Programming 
Unix System Programming 
WTF 
WTF 
WTF 

和第二次我得到:再次

Unix System Programming 
WTF 
Unix System Programming 
Unix System Programming 
WTF 
Unix System Programming 
WTF 
WTF 

次和第三次的不同。为什么会发生?我无能为力;请详细解释。

+1

'doit()'中未使用的变量'pid'。函数中的“返回”也不是必需的。 –

回答

3

当你分叉一个新的进程时,父和子都同时运行。他们执行各自的printf()陈述的顺序是不可预知的 - 有时父母会先打印,有时孩子会打印。

如果您将PID包含在输出中,您可能会更好理解,因此您可以看到哪一个进程正在打印每一行。所以它更改为:

printf("%d: Unix System Programming\n", getpid()); 

printf("%d: WTF\n", getpid()); 

你应该看到的是,每个进程打印Unix System ProgrammingWTF之前,但工艺顺序将被混合起来。

+0

好的@Barmar!想知道一个额外的事情,如果我在这个程序中有两个叉,所以我可以期望至少有4个子进程在运行&一个父进程(这是代码执行本身)。在这里,总共有2个打印语句。因此4 * 2 = 8次输出。我是正确的还是不同的情况? –

+2

如果你有2个叉子,你会得到4个过程,而不是4个子过程。第一个叉子创建1个孩子。第二个分支在父代和子代都运行,并且每个都创建一个新进程。所以你最终得到1个原始程序,2个子程序,1个孙子程序。 – Barmar

+0

但是你是正确的,他们每个人打印2行,所以你得到8输出线。 – Barmar

2

您看到的输出来自不同的进程。一旦fork成功,您将得到一个不同的子进程(以及父进程)。由于它们来自不同的进程,因此无法保证一个进程何时轮到执行。所以不同流程的输出会混合在一起,而且每次运行的顺序可能会有所不同。

如果你想确保父进程和子进程以某种特定的顺序运行,那么你必须同步它们,这通常比分叉要多得多。 (它可能需要等待操作或使用管道 - 取决于你想要的同步性质。)