如何通过子进程创建三个子进程?

时间:2020-04-17 09:16:44

标签: c parallel-processing fork

我想从主流程(P0)的子流程中创建三个子流程。所以像->

P0 -> P1 ->P2  
             ->P3
             ->P4

但是,每当我运行它时,我都会得到(对于进程P2,P3,P4)主进程的ppid(ppid = 1)。

我正在使用fork()系统调用来创建子代,并且该程序的实现在C中进行。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main()
{
    int i, pid1, pid2;
    pid1 = fork();
    printf("Pid1 pid -> %d ppid -> %d\n",getpid(),getppid());
    if(pid1 != 0)
    {
        pid2 = fork();
        printf("Pid2 pid -> %d ppid -> %d\n",getpid(),getppid());
        if(pid2 == 0)
        {
            for(i=2; i<5; i++)
            {
                //if(fork()==0)
                //{
                    printf("Child %d pid -> %d Parent -> %d\n",i+1,getpid(),getppid());
                //}
                exit(0);
            }
        }
        else 
        {
            printf("Pid2 father process \n");
        }  
    }
    else 
    {
        printf("Pid1 child process\n");

    }
}

2 个答案:

答案 0 :(得分:0)

警告,在

pid1 = fork();
printf("Pid1 pid -> %d ppid -> %d\n",getpid(),getppid());

printf 是在P0和P1中完成的,这一点还不清楚,您必须先检查 pid1 才能打印出您的位置。

警告,

pid1 = fork();
...
if(pid1 != 0)
{
   pid2 = fork();

您应该在再次 fork 时进入P1,但由于 pid1 不为0

,您仍处于P0中

还建议检查 fork 是否成功(返回值不为-1),并等待子进程终止而不是在退出之前退出父进程。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>

int main()
{
    int pid1 = fork();

    if (pid1 == -1)
      perror("cannot fork p1");
    else if(pid1 != 0)
    {
      int pid2;

      printf("In P1, Pid1 pid -> %d ppid -> %d\n", getpid(), getppid());

      pid2 = fork();

      if (pid2 == -1)
        perror("cannot fork p2");
      else if (pid2 == 0) {
        int pid3[2];
        int i;

        printf("in P2, Pid2 pid -> %d ppid -> %d\n", getpid(), getppid());

        for (i = 0; i != 2; ++i) {
          pid3[i] = fork();
          if (pid3[i] == -1)
            perror("cannot fork P2 child");
          else if (pid3[i] == 0) {
            printf("in Child %d pid -> %d Parent -> %d\n",i+1,getpid(),getppid());
            return 0;
          }
          else
            puts("in p2");
        }
        waitpid(pid3[0], 0, 0); /* erroned if fork failed, whatever */
        waitpid(pid3[1], 0, 0); /* erroned if fork failed, whatever */
      }
      else {
        puts("still in p1");
        waitpid(pid2, 0, 0);
      }
    }
    else 
    {
      puts("in P0");
      waitpid(pid1, 0, 0);
    }

    return 0;
}

编译和执行:

/tmp % ./a.out
In P1, Pid1 pid -> 68995 ppid -> 54669
in P0
still in p1
in P2, Pid2 pid -> 68997 ppid -> 68995
in p2
Child 1 pid -> 68998 Parent -> 68997
in p2
Child 2 pid -> 68999 Parent -> 68997
/tmp % 

请注意,根据 getppid 的手册,书面的pid是错误的:

然后在子级中对getpid()的调用将返回错误的值(准确地说:它将返回父级进程的PID)

答案 1 :(得分:0)

您想要以下内容:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main()
{
    int i, pid1, pid2;

    pid1 = fork();
    printf("Pid1 pid -> %d ppid -> %d\n",getpid(),getppid());

    // parent
    if(pid1 != 0)
    {
        pid2 = fork();
        printf("Pid2 pid -> %d ppid -> %d\n",getpid(),getppid());

        if(pid2 == 0)
        {
            for(i=2; i<5; i++)
            {
                if(fork()==0)
                {
                    printf("Child %d pid -> %d Parent -> %d\n",i+1,getpid(),getppid());
                    // some functionality here
                    exit(0);
                }
            }
            exit(0);
        }
        else 
        {
            printf("Pid2 father process \n");
        }  
    }
    else 
    {
        printf("Pid1 child process\n");

    }
}

在我的机器中提供以下输出:

Pid1 pid -> 17764 ppid -> 32242
Pid1 pid -> 17765 ppid -> 17764
Pid1 child process
Pid2 pid -> 17764 ppid -> 32242
Pid2 father process
Pid2 pid -> 17766 ppid -> 17764
Child 3 pid -> 17767 Parent -> 17766
Child 4 pid -> 17768 Parent -> 17766
Child 5 pid -> 17769 Parent -> 17766

因此,具有以下层次结构:

Parent (pid: 17764) -> C1 (17765) -> C2 -> 17666
                                          C3-> 17767
                                          C4-> 17768
                                          C5-> 17769