Как я могу создать три дочерних процесса дочерним процессом? - PullRequest
1 голос
/ 17 апреля 2020

Я хочу создать три дочерних процесса из дочернего процесса основного процесса (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 голосов
/ 17 апреля 2020

Вы хотите что-то вроде следующего:

#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
0 голосов
/ 17 апреля 2020

Предупреждение, в

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

printf выполняется как в P0, так и в P1, это вообще неясно, вы должны сначала проверить pid1 перед чтобы напечатать, где вы находитесь.

Предупреждение, в

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

вы должны быть в P1, когда вы снова fork , но вы все еще в P0, потому что pid1 не равен 0

Также рекомендуется проверить fork success (возвращаемое значение не равно -1) и дождаться ребенка (ren ) завершение, а не выход из родительского процесса до

#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 % 

Обратите внимание, что записанный pid неверен, из руководства getppid :

тогда вызов getpid () в дочернем элементе вернет неправильное значение (точнее: вернет PID родительского процесса)

...