解释涉及fork()的C程序的输出

解释涉及fork()的C程序的输出,c,fork,C,Fork,运行此程序会打印“forked!”7次。有人能解释一下“forked!”怎么被打印了7次吗 #include<stdio.h> #include<unistd.h> int main(){ fork() && fork() || fork() && fork(); printf("forked!\n"); return 0; } #包括 #包括 int main(){ fork()&&fork()| | fork()&

运行此程序会打印“forked!”7次。有人能解释一下“forked!”怎么被打印了7次吗

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

int main(){

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

  printf("forked!\n");

  return 0;
}
#包括
#包括
int main(){
fork()&&fork()| | fork()&&fork();
printf(“分叉!\n”);
返回0;
}

与我在评论中所说的不同,这与缓冲无关。这个过程是分岔的。父级执行第二个fork,而子级短路第二个fork并执行第三个fork。第一个孙子将第一个
&&
计算为false并执行第三个fork。这将产生2个进程,其中一个进程计算第4个fork。同时(或之前,或之后…存在竞争条件!),另一个子进程在评估
|
的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; } 

这里使用了几个概念,第一个是知道
fork
做什么,以及在某些情况下它返回什么。很快,当它被调用时,它会创建一个调用方的重复进程,并在子进程中返回
0
false
,对于逻辑表达式),在父进程中返回非零(
true
)。 实际上,如果出现错误,它可以返回一个负值(非零值),但这里我们假设它总是成功的

第二个概念是逻辑表达式的短路计算,例如
&&
|
,具体来说,
0&&fork()
不会调用
fork()
,因为如果第一个操作数是
false
(零),那么就不需要计算第二个操作数。类似地,
1 | | fork()
也不会调用
fork()

还请注意,在子进程中,表达式的计算将在与父进程相同的点上继续进行

此外,请注意,由于优先级的原因,表达式按以下顺序计算:

(fork() && fork()) || (fork() && fork())
这些观察结果会引导你找到正确的答案

考虑一下
fork()&&fork()


这里我们创建了三个进程,其中两个返回
false
作为结果,另一个返回
true
。然后对于
|
我们让所有进程返回
false
试图再次运行相同的语句,因此我们有
2*3+1=7
作为答案。

可能会重复1000个其他问题…这是由于缓冲,除非您的问题更具体。您希望打印多少次?尝试将布尔表达式写成嵌套的if then elses,然后绘制递归树。只是为了澄清:fork为子级返回0(false),为父级返回子级的PID(true)
   fork()        
  /     \
false   true && fork()
                /   \
             false  true