简体   繁体   English

涉及fork()的C程序输出的说明

[英]Explanation of a output of a C program involving fork()

Running this program is printing "forked!" 运行这个程序正在打印“分叉!” 7 times. 7次。 Can someone explain how "forked!" 有人可以解释一下“分叉!” is being printed 7 times? 正在打印7次?

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

int main(){

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

  printf("forked!\n");

  return 0;
}

There're several concepts being used here, first one is knowing what fork does and what it returns in certain circumstances. 这里使用了几个概念,第一个是知道fork在什么情况下做什么以及它返回什么。 Shortly, when it gets called, it creates a duplicate process of the caller and returns 0 ( false for logical expressions) in child process and non-zero ( true for logical expressions) for parent process. 很快,当它被调用时,它会创建一个重复的调用者进程,并在子进程中返回0 (逻辑表达式为false ),父进程返回非零(逻辑表达式为true )。 Actually, it could return a negative (non-zero) value in case of an error, but here we assume that it always succeeds. 实际上,它可以在出现错误时返回负(非零)值,但在这里我们假设它总是成功。

The second concept is short-circuit computation of logical expressions, such as && and || 第二个概念是逻辑表达式的短路计算,例如&&|| , specifically, 0 && fork() will not call fork() , because if the first operand is false (zero), then there's no need to compute the second one. ,具体来说, 0 && fork() 不会调用fork() ,因为如果第一个操作数为false (零),则不需要计算第二个操作数。 Similarly, 1 || fork() 同样, 1 || fork() 1 || fork() will not call fork() neither. 1 || fork()也不会调用fork()

Also note that in child processes the computation of the expression continues at the same point as in the parent process. 另请注意,在子进程中,表达式的计算将继续与父进程中的计算相同。

Also, note that the expression is computed in the following order due to precedence: 另请注意,由于优先级,表达式按以下顺序计算:

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

These observations should lead you to the correct answer. 这些观察结果应该引导您找到正确的答案。

Consider the simplified example of fork() && fork() 考虑fork() && fork()的简化示例

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

So here we have three processes created, two of which return false as the result and one returning true . 所以这里创建了三个进程,其中两个返回false作为结果,一个返回true Then for || 然后为|| we have all the processes returning false trying to run the same statement again, so we have 2 * 3 + 1 = 7 as the answer. 我们让所有进程返回false尝试再次运行相同的语句,所以我们有2 * 3 + 1 = 7作为答案。

Unlike I stated in my comment, this is not about buffering. 与我在评论中提到的不同,这不是关于缓冲。 The process forks. 过程分叉。 The parent executes the 2nd fork, while the child short circuits the second and executes the 3rd. 父进程执行第二个分叉,而子进程短路第二个分支并执行第三个分支。 The first grandchild evaluates the first && as false and executes the 3rd fork. 第一个孙子评估第一个&&为false并执行第3个fork。 That spawns 2 processes, one of which evaluates the 4th fork. 这产生了2个进程,其中一个进程评估第4个分支。 Meanwhile (or before, or after...there's a race condition!), the other child has become 3 processes while evaluating the RHS of the || 与此同时(或之前或之后......存在竞争条件!),另一个孩子在评估||的RHS时已成为3个过程 . In all, 7 processes end up running. 总之,7个进程最终运行。 Draw a tree. 画一棵树。

To simplify the calculation, consider: 要简化计算,请考虑:

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; } 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM