如何在工作流树中表示 fork() && fork()?

How to represent fork() && fork() in workflow tree?

在 C 中,fork() 函数将 return 父进程的非零值和子进程的零值。

在使用 && 或 || 等逻辑表达式时,我在试图了解这些代码的工作原理时感到困惑。我如何通过图论在树中显示它们?代码是如何执行的?

#include <stdio.h> 
#include <unistd.h> 
int main() 
{ 
   fork(); 
   fork() && fork(); // or fork() || fork() 

   printf("forked\n"); 
   return 0; 
} 

短路评估

For the built-in logical AND operator, the result is true if both operands are true. Otherwise, the result is false. This operator is short-circuiting: if the first operand is false, the second operand is not evaluated

所以对于这一行:

fork() && fork()

第一个 fork 在 child 中计算 true 并且 child 将再分叉一个(并且 parent 完成此语句由于短路)。

相反的情况发生在:

fork() || fork()

并且 parent 将再分叉一个。

等效代码

一种等效的写法是使用 if 语句:

if (fork()){
  fork();
}

if (!fork()){
  fork();
}

逻辑 AND (&&) 和逻辑 OR (||) 运算符都使用短路行为。

expr1 && expr2:如果 expr1 符合逻辑 0false),则不评估 expr2
expr1 || expr2:如果 expr1 符合逻辑 1true),则不会计算 expr2

使用逻辑短路时,仅当第一个操作数 expr1.

假设父进程和子进程中的所有 fork() 调用都成功,分叉进程树将如下所示:

 parent process
     |
     |
   fork()    // first fork
   -----     // below in the tree, RV is fork() returned value
     |
     |----child process [RV: 0]--
     |                          |
   [RV: child PID]              |
     |                          |
   fork() && fork()            fork() && fork()
   ------                      ------
     |                          |
     |                          |--child process [RV: 0]--
     |                          |                        |
     |                         [RV: X (child PID)]       |
     |                          |                      0 && fork()   
     |                          |                   // due to && short-circuiting behavior, 
     |                          |                   // fork() will not be called
     |                          |                        |
     |                          |                       Print "forked"
     |                          |                       Exit
     |                          |
     |                          |
     |                    X && fork()   // X is a non zero value and hence the fork() will be called
     |                         ------
     |                          |
     |                          |--child process [RV: 0]--
     |                          |                        |
     |                        [RV: child PID]            |
     |                          |                        |
     |                         Print "forked"           Print "forked"
     |                         Exit                     Exit
     |
     |--child process [RV: 0]--
     |                        |
   [RV: X (child PID)]        |
     |                      0 && fork()
     |                      // due to && short-circuiting behavior, fork() will not be called
     |                        |
     |                        |
     |                      Print "forked"
     |                      Exit
     |
X && fork()   // X is a non zero value and hence the fork() will be called
     ------
     |
     |--child process [RV: 0]--
     |                        |
   [RV: child PID]            |
     |                        |
     |                        |
   Print "forked"           Print "forked"
   Exit                     Exit

希望这对您理解执行有所帮助。自己尝试 fork() || fork() 表达式。如果您还有其他问题,请告诉我。