控制C中的前叉

时间:2009-08-06 13:00:48

标签: c tree fork

我有一个看起来像这样的C文件:

#include <stdio.h> 
#include <sys/types.h> 
#include <unistd.h> 
int main () 
{ 
    pid_t child_pid; 
    printf ("The PID is %d\n", (int) getpid ()); 
    child_pid = fork (); 
    if (child_pid != 0)
    { 
        printf ("this is the parent process, with PID %d\n", 
        (int)getpid()); 
        printf ("the child's PID is %d\n", (int) child_pid); 
    } 
    else 
        printf ("this is the child process, with PID %d\n", 
        (int)getpid()); 
    return 0; 
} 

我需要修改它以产生一个看起来像

的层次结构
parent (0)
  |
  +---> child (1)
  |
  +---> child (2)
          |
          +----> child (3)
          |
          +----> child (4)
                  |
                  +----> child (5)
                  |

基本上是一个树形结构,每个第二个孩子生两个新孩子。据我了解,当我fork()进程时,每个进程将同时运行。在fork()语句中添加if似乎可以正常工作并正确创建进程0到2,因为只有父进程才会创建新的分支。但我不知道如何制作进程2 fork而不是1.任何想法?

4 个答案:

答案 0 :(得分:2)

嗯,第一个分叉将创建进程1。进程2将由if语句中的fork创建。因此,为了让进程2 fork也是如此,如果第二个fork没有返回0,则在if语句中再次进行fork。

插图:

if(fork) {
    // Inside process 0
    if(fork) {
        // still in process 0
    } else {
        // in process 2
        if(fork) {
          // still in process 2
        } else {
          // in prcess 3
        }
        // and so on
    }
} else {
    // Inside process 1
}

答案 1 :(得分:2)

儿童在分叉时获得父母的州的副本。

因此,如果父母有一个计数器或其他属性,那么孩子们将在分叉时看到该值(但如果父母随后改变它,则不会)。

答案 2 :(得分:2)

我不知道你为什么要这样做,但通常只有父进程执行fork。这也可能更容易设计。当你在for循环中执行fork()时,你可以直接控制所创建的进程。

请注意,fork()是一项相对昂贵的操作,特别是如果您想创建许多进程。可以使用更轻量级的替代品vfork和螺纹,但我无法判断它们是否也符合您的需求。

答案 3 :(得分:1)

一个老问题,但仍然是一个有趣的问题。 fork()的{​​{3}}告诉我们返回值:

  

成功时,子进程的PID在父进程中返回,并在子进程中返回0。失败时,在父项中返回-1,不创建子进程,并正确设置errno。

所以我们知道fork()向孩子返回0,我们可以用它作为控制机制:

int main()
{
   // Here we're in the parent (0) process

   if(fork())  // This starts the chain, only the parent will do this
    if(!fork()) //the child will pass this, the parent will skip it
     for(count = 0; counter < number_of_processes; counter++) //now the 2nd child loops
     {
         if(fork())
             if(!fork());
         else
             break;
     }

让我们给它一些数字:

//parent (18402)
if(fork()) // spawns 18403, parent 18402 keeps going
  if(!fork()) // spawns 18404, parent 18402 drops to the end of main()
    for(count = 0; count < number_of_processes; conter++) // 18404 enters here
      if(fork())  // 18404 forks 18405 and then goes on
        if(!fork());  // 18404 spawns 18406 before leaving, 18406 restarts the loop
        else
          break; // 18404 breaks out there
      else
          break; //18405 leaves the loop here

所以经过一次迭代我们得到了:

  18402
    |
    +---> 18403
    |
    +---> 18404
            |
            +----> 18405
            |
            +----> 18406
                     |

在此之后,我们将继续循环两个新进程,其中第二个进程将继续迭代,直到您按需要进行多次传递。