Как изменить порядок создания процессов? - PullRequest
2 голосов
/ 25 апреля 2020

Мне нужно создать дерево процессов, как на этом изображении:
enter image description here

Мне удалось создать такое дерево, но с небольшой разницей. P4 - это фактически P3, а P3 - это P4. Я создал их по порядку, потому что не могу придумать, как «прикрепить» P4 к P1 и P3 к P2.

Это то, что я написал до сих пор:

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

int main(int argc, char **argv){

    printf("Main pid is %d\n", getpid());

    pid_t pid1[2];
    pid_t pid2[4];
    pid_t pid3a, pid3b;

    //FIRST LAYER
    for(int i = 0; i < 2; i++){
        pid1[i] = fork();

        if(pid1[i] == 0){
            printf("[son] pid %d from [parent] pid %d\n", getpid(), getppid());

            //SECOND LAYER
            if ( i == 0){
                for(int j = 0; j < 4; j++){
                    pid2[j] = fork();

                    if (pid2[j] == 0){
                        printf("\t[son] pid %d from [parent] pid %d\n", getpid(), getppid());

                        //THIRD LAYER
                        if (j == 1){
                            pid3a = fork();

                            if (pid3a == 0){
                                printf("\t\t[son] pid %d from [parent] pid %d\n", getpid(), getppid());
                                exit(0);
                            }

                            waitpid(pid3a, NULL, 0);
                        }


                        if (j == 2){
                            pid3b = fork();

                            if (pid3b == 0){
                                printf("\t\t[son] pid %d from [parent] pid %d\n", getpid(), getppid());
                                exit(0);
                            }

                            waitpid(pid3b, NULL, 0);
                        }
                        //END THIRD LAYER


                        exit(0);
                    }
                }
            //END SECOND LAYER

                for(int j = 0; j < 4; j++)
                    waitpid(pid2[j], NULL, 0);
            }


            exit(0);
        }
    }

    for(int i = 0; i < 2; i++)
        waitpid(pid1[i], NULL, 0);
    //END FIRST LAYER

    return 0;
}

Что я могу изменить, чтобы добиться этого?

1 Ответ

1 голос
/ 25 апреля 2020

Для разветвления лучше один раз, чем нужных вам путей. Посмотрите на следующий код, основанный на графике (без переключения P3 и P4)

void doP1(){
  if(fork())
    doP2();
  else
    doP4();
}

void doP2(){
  if(fork())
    doP3();
  else if(fork())
    doP5();
  else if(fork())
    doP6();
  else
    doP7();
}

void doP3(){
  return;
}

void doP4(){
  return;
}

void doP5(){
  doP8();
}

void doP6(){
  doP9();
}

void doP7(){
  return;
}

void doP8(){
  return;
}

void doP9(){
  return;
}

int main(){
  doP1();
}

Я разделил каждый узел дерева в его собственную функцию, которая ничего не делает, кроме разветвления в виде графика.

Когда путь к данным разделяется на два, вам не нужно создавать два дочерних потока, вам просто нужно создать один. Родитель идет в одну сторону, а потом - в другую.

то есть P1 должен вызывать fork только один раз, P2 должен вызывать fork только три раза, P5 и P6 вообще не должны вызывать fork

Я надеюсь, что это отвечает на ваш вопрос!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...