【问题标题】:Concurrent Processes using fork()使用 fork() 的并发进程
【发布时间】:2016-10-19 21:54:31
【问题描述】:

我得到以下代码:

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 正在执行 |大孩子 所有孩子都创建了|

创建的所有孩子 |家长

我知道这些输出是由每个进程创建的,但我无法跟踪它们以了解如何这些输出发生。我知道fork() 创建了一个进程,if (fork() == 0) 表示它是一个子进程,但如果有人可以帮助我了解 Child 0 执行 | 之外的答案来自哪里,谢谢。我相信|只是对当前正在运行的进程的描述。为什么child 1 可以创建“孙子”,而子 0 不能?

【问题讨论】:

  • 请编辑您的问题,用明确的内容替换“可能发生的输出的可能排列”。确保清楚地解释它后面的引用块是什么。 (这是某种进程输出和标签的乱码,标签中的进程名称没有解释。)(另外,“Child 1 execution”只会输出两次。)见我的回答。

标签: c concurrency process fork scheduling


【解决方案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 是显示“Child 0 execution”的 printf 语句,child1 是“Child 1 execution”的语句,“end”是显示“All children created”的 printf 语句。

从图中可以看出,您将获得 1x child0、2x child1 和 4x“All children created”。

更新@bkennedy

这是另一个仅显示进程视图的视图,其中 P0 是主(原始)进程,“end”表示每个进程的完成:

                P0
                /|
               / |
              /  |\
            P1   | \
            |    |  \
            |    |  P2   
           /|    |   |
          / |    |   |
         /  |    |  end
        /  end   |   
       /         | 
      P3        end  
      |             
      |             
     end     
  • 实际上有 4 个进程:P0(主)、P1、P2 和 P3。
  • P1 是 P0 的第一个孩子;它显示“孩子 0 正在执行”。
  • P2 是 P0 的第二个孩子;它显示“孩子 1 正在执行”。 P2 从不创建任何子节点,它只是以 printf 语句结束。
  • P3 是 P1 的第一个(也是唯一的)孩子。
  • 每个进程在完成后都会显示“所有子进程已创建”。

记住:

  • P0(主)经过 2 次 fork 调用,因此有 2 个孩子。
  • P1 经历了 1 个 fork 调用,因此是单个子 (P3)。
  • P2 从不进行分叉调用。

就是这样,没有其他进程创建。我不知道如何更好地向您解释这一点。

【讨论】:

  • 为什么child0 可以生另一个孩子,而child1 不能?
  • 在图中,我描绘了各种进程的输出。因此,所描绘的两个 child1 不是相同的进程。其实一共有4个进程:main、child0、child1(1)、child1(2)。
  • 你能解释一下为什么 child0 产生另一个孩子而 child1 不能吗?
【解决方案2】:

在第一个 fork 和它所在的 if 语句之后,“子 0 执行”进程及其静默父进程 main 继续执行下一个 if 语句。在那里,它们都产生了一个“child 1 execution”进程,同时保持沉默。所有这四个进程,即main,“child 0正在执行”进程,main的“child 1正在执行”进程和“child 0正在执行”进程的“child 1执行进程”,在第二次fork和if语句之后继续打印“所有创建的孩子”。

输出“Child 0 execution”中的一个,输出“Child 1 execution”中的两个,输出“All children created”中的四个。

为什么孩子 1 可以创建“孙子”而孩子 0 不能?

没有“孩子 1”创建一个孩子。 Main 和“child 0”各自创建一个“child 1”。输出显然将“child 0”的“child 1”称为 main 的“Grand child”。所以没有“child 1”创建一个孩子,main 和“child 0”都产生一个“child 1”。所以你的问题关于“child 1”(其中有两个)和“child 0”都是错误的。

这些输出是如何发生的

引用的“输出”似乎调用 main Parent,“child 0”进程 Child 0,main 的“child 1”进程 Child 2 和“child 0”进程的“child 1”进程 Grand child。因此,您需要区分“输出”对进程的命名以及这些进程正在输出的内容。它还有三行输出“Child 1 execution”,这是错误的。但是应该告诉我们那个“输出”应该是什么。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-24
    • 2014-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多