使用fork()的并发进程

时间:2016-10-19 21:54:32

标签: c concurrency process fork scheduling

我收到以下代码:

main()
{
int i, rc;
 for (i = 0; i<=1; i++)
 {
   if( (rc=fork()) == 0)
   {
    printf("Child %d executing\n",i);
   }  /*end if*/
 } /*end for*/ 
}
printf("All children created\n");

我也得到了可能出现输出的可能排列的解决方案。

  

子0执行|

     

子1执行|孩子1    所有孩子都创建了|

     

子1执行|孩子2    所有孩子都创建了|

     

子1执行|大孩子    所有孩子都创建了|

     

所有孩子都创建了|父

我知道这些输出是由每个进程创建的,但我只是在跟踪它们以理解 HOW 这些输出时遇到了问题。我知道fork()创建了一个流程,而if (fork() == 0)意味着它是一个子流程,但是如果有人可以帮助我理解 Child 0执行| 之外的答案,那就谢谢了。我相信|只是描述当前正在运行的进程。怎么来child 1可以创造一个“大孩子”但是孩子0不能?

2 个答案:

答案 0 :(得分:1)

首先,如果循环展开,代码和行为将更容易理解。然后代码变为:

int rc;

if ((rc = fork()) == 0)
    printf("Child 0 executing\n");                                          

if ((rc = fork()) == 0)
    printf("Child 1 executing\n");

printf("All children created\n");

然后,为了帮助理解要进行的操作,最好将流程层次结构绘制为树。这是它的ASCII版本:

                main
                /|
               / |
              /  |\
          child0 | \
            |    |  \
            |    | child1
           /|    |   |
          / |    |   |
         /  |    |  end
        /  end   |   
       /         | 
    child1      end  
      |             
      |             
     end     

在图中,child0是printf语句,显示&#34;子0执行&#34 ;, child1是语句&#34;子1执行&#34;和&#34;结束&#34;是printf语句显示&#34;所有孩子都创建&#34;。

从图表中可以看出,你将得到1x child0,2x child1和4x&#34;所有孩子都被创造了#34;。

更新@bkennedy

这是另一个仅显示过程视图的视图,其中P0是主(原始)过程,&#34;结束&#34;指示每个过程&#39;完成:

                P0
                /|
               / |
              /  |\
            P1   | \
            |    |  \
            |    |  P2   
           /|    |   |
          / |    |   |
         /  |    |  end
        /  end   |   
       /         | 
      P3        end  
      |             
      |             
     end     
  • 实际上有4个过程:P0(主要),P1,P2和P3。
  • P1是P0的第一个孩子;它显示&#34; Child 0正在执行&#34;。
  • P2是P0的第二个孩子;它显示&#34; Child 1正在执行&#34;。 P2永远不会创建任何子项,它只是用printf语句完成。
  • P3是P1的第一个(也是唯一的)子女。
  • 每个过程显示&#34;所有孩子创建&#34;当他们完成时。

记住:

  • P0(主要)经过2次叉号,因此是2个孩子。
  • P1通过1次叉号,因此是单个孩子(P3)。
  • P2永远不会进行分叉呼叫。

就是这样,没有其他流程创建。我不确定如何更好地向你解释这一点。

答案 1 :(得分:0)

在第一个fork和它所在的if语句之后,&#34; child 0执行&#34;进程及其静默父进程main继续下一个if语句。在那里他们都生产了一个孩子1执行&#34;保持沉默的过程。所有这四个过程,即主要的,&#34;子0执行&#34;过程,主要&#34;孩子1执行&#34;处理&#34;并且&#34;孩子0执行&#34;进程&#34;孩子1执行过程&#34;,继续第二个分支和它打印的if语句&#34;所有孩子创建&#34;。

其中一个&#34;孩子0正在执行&#34;输出&#34; Child 1执行&#34;输出,以及四个&#34;所有孩子创建&#34;输出。

  

孩子1怎么能创造一个“大孩子”#34;但是孩子0不能?

否&#34;孩子1&#34;创造一个孩子。主要和&#34;孩子0&#34;每个人创造一个孩子1&#34;。输出显然叫做孩子0&#34;&#34;孩子1&#34; &#34;大孩子&#34;主要的。所以没有孩子1&#34;创造一个孩子,主要和孩子0&#34;生产一个孩子1&#34;。所以你的问题对于孩子1和孩子都是错误的。 (其中有两个)和&#34;孩子0&#34;。

  

这些输出如何发生

引用的&#34;输出&#34;似乎称为主要父母,孩子0&#34;处理孩子0,主要&#34;孩子1&#34;处理孩子2和孩子0&#34;过程&#34;孩子1&#34;过程大孩子。所以你需要区分&#34;输出&#34;命名流程以及这些流程输出的内容。它还有三行输出&#34;子1执行&#34;,这是错误的。但应该告诉我们那&#34;输出&#34;应该是。