2012-06-21 39 views
4

运行此程序的输出的说明被打印“分叉”! 7次。有人可以解释“叉”!正在打印7次?一个C程序涉及叉()

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

int main(){ 

    fork() && fork() || fork() && fork(); 

    printf("forked!\n"); 

    return 0; 
} 
+3

的其他问题1000可能的复制......这是由于缓冲,除非你的问题是更具体。 –

+0

您希望打印多少次? – RedX

+0

我希望它是5 – sushil

回答

5

有在这里所使用的几个概念,第一个是知道什么fork不和它返回在某些情况下是什么。不久,它被调用时,会创建一个调用方的重复进程,并为父进程返回子进程的0false)和子进程的非零(逻辑表达式的true)。 实际上,它可以在一个错误的情况下返回负(非零)值,但在这里我们假设它总是成功。

第二个概念是逻辑表达式的短路计算,如&&||,具体而言,0 && fork()呼叫fork(),因为如果第一个操作数是false(零),那么就没有必要计算第二个。同样,1 || fork()也不会拨打fork()

还要注意,在孩子处理表达式的计算在同一地点继续在父进程。

另外,还要注意表达的计算按以下顺序由于优先级:

(fork() && fork()) || (fork() && fork()) 

这些意见应导致你正确的答案。

考虑的fork() && fork()

fork()   
/ \ 
false true && fork() 
       / \ 
      false true 

所以这里的简单的例子,我们已经创建了三个过程,其中两个返回false的结果和一个返回true。那么对于||我们返回false试图再次运行同一语句中的所有进程,所以我们2 * 3 + 1 = 7的答案。

4

不像我在我的评论中说的,这不是关于缓冲。过程分叉。父母执行第二个分支,而孩子将第二个分支短路并执行第三个分支。第一个孙子将第一个&&评估为false并执行第三个分支。产生2个进程,其中一个进程评估第4个分支。同时(或之前或之后......有竞赛状况!),另一个孩子在评估||的RHS时已成为3个进程。总共有7个过程最终运行。画一棵树。

为了简化计算,考虑:

int f(void) 
{ 
    int k; 
    k = fork(); 
    printf("%d\n", (int) getpid()); 
    fflush(stdout); 
    return k; 
} 

int main(void) { f() && f() || f() && f(); return 0; } 
+1

仅供说明:fork为孩子返回0(false),为父母返回孩子的PID(true) –