【问题标题】:How to represent fork() && fork() in workflow tree? [duplicate]如何在工作流树中表示 fork() && fork()? [复制]
【发布时间】:2020-02-29 13:21:25
【问题描述】:

在 C 中,fork() 函数将为父进程返回一个非零值,为子进程返回零值。

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

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

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

【问题讨论】:

  • 至于您的问题,请考虑逻辑运算符&amp;&amp;|| 使用的short-circuit evaluation,以及更多fork 返回的内容,以及“false”和“ true" 值。
  • fork() &amp;&amp; fork():考虑到&amp;&amp; 是短路的。执行此操作的进程调用两者。它的第一个子进程(第一个接收 0)不执行第二个。 (第一个和第二个子进程以printf() 继续。)
  • fork() 也可以在出错时返回 -1(非零),因此请务必考虑这一点。

标签: c multithreading tree fork


【解决方案1】:

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

expr1 &amp;&amp; expr2:如果expr1 是逻辑0false),则不评估expr2
expr1 || expr2:如果expr1,则不评估expr2是合乎逻辑的1 (true)。

通过逻辑短路,第二个操作数 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() 表达式。如果您还有其他问题,请告诉我。

【讨论】:

    【解决方案2】:

    短路评估

    对于内置的逻辑 AND 运算符,如果两者都为真,则结果为真 操作数为真。否则,结果为假。这个运算符是 短路:如果第一个操作数为假,则第二个操作数为 未评估

    所以对于这一行:

    fork() && fork()
    

    第一个fork 在子级中被评估true,子级将再分叉一个(由于短路,父级已完成此语句)。

    相反的情况发生在:

    fork() || fork()
    

    父母会再分叉一个。

    等效代码

    同样的写法是使用if 语句:

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

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

    【讨论】:

      猜你喜欢
      • 2015-01-25
      • 1970-01-01
      • 2020-02-01
      • 2013-02-12
      • 2013-12-09
      • 2017-01-28
      • 2011-03-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多