叉树图

时间:2016-04-02 16:00:41

标签: c concurrency fork

好的,所以我正在阅读过去的论文,而且我遇到一个关于fork()函数的问题here是我应该使用C重新创建的图。

我知道fork()向子节点返回0,子节点PID返回父节点,但很难理解这一切是如何工作的。

我想出了以下内容,但我觉得它不起作用:

while(fork() == 0) {
  if (fork() == 0) break;
}

任何帮助都将不胜感激。

4 个答案:

答案 0 :(得分:3)

调试您当前的代码:

while(fork() == 0) {

这一行创建了一个子进程(我们称之为子进程1)。父进程不进入while循环。子进程1进入循环。

if (fork() == 0) break;

这一行现在正由子进程1执行,从它分支创建子进程2.如果我们当前正在执行子进程2(这个fork调用的'child'),我们就会中断。如果我们正在执行子进程1,我们将继续while循环的下一次迭代。

现在我们有了以下流程树:

    . p
   /
  . child process 1
 /
. cp2

使用子进程1执行while循环的方式与我们传入父进程时的模式相同,结果是:

    . p
   /
  . child process 1
 /    \
. cp2  . cp3
      /
     . cp4

<强>解决方案:

我们的最终目标是创建2个子进程,并继续从第二个子进程分叉。

while (1) {
    pid_t c1 = fork();
    assert(c1 >= 0); // check fork error
    if (c1 == 0) break; // don't make more children from c1
    pid_t c2 = fork();
    assert(c2 >= 0);
    if (c2 > 0) break; // don't make additional children from parent
}

答案 1 :(得分:1)

如果要从每个child2(和初始父级)创建两个子进程:

#define MAX 6

int value;
unsigned u = 0;

do{
    if((value = fork()) == 0) // child1
        break;
    else if(value < 0) // error
        break;

    // parent

    if((value = fork()) > 0) // parent
        break;
    else if(value < 0) // error
        break;

    // child2

    u++;
}while(u < MAX);

如果您不想设置MAX,请使用while(1)

您的程序没有为第一个父级创建child1。

答案 2 :(得分:0)

您走在正确的轨道上,因为您需要在循环中创建新流程。 我认为图像意味着你应该让原始父母继续在无限循环中创建进程,并且孩子(所有兄弟姐妹)完成他们的工作并退出。

该图片也存在问题,因为fork来电并没有真正创建两个孩子,只有一个孩子然后父母继续,这意味着&#34; child2` in那个图像真的只是&#34;父母&#34;。

因此要实现创建该树的东西,我会做类似

的事情
for (;;)
{
    int ret = fork();
    if (ret == 0)
    {
        // In the child, "child1" in the image
        // Do whatever is supposed to be done
        exit(0);  // Exit the child
    }
    else if (ret == -1)
    {
        // Error, handle it somehow
    }
    else
    {
        // In parent, what is called "child2" in the image
        // Do something useful here...

        // Then wait for the child to exit
        wait(NULL);
    }

    // Let the loop iterate, to create a new "child1"
}

答案 3 :(得分:0)

编写代码并在一张纸上添加变量值框并手动执行。每次调用fork()时:

  • 制作您的床单复印件,
  • 在原文上为fork的返回提供了一些唯一的非负值,
  • 副本上的
  • 将fork的返回值赋予0,
  • 继续按照您想要的任何顺序执行所有纸张上的说明。

这是理解将会发生什么的好方法。