использование fork () для отображения дерева процессов - PullRequest
0 голосов
/ 12 февраля 2020

Мне нужно создать дерево процессов и отобразить родительский и дочерний элементы на графике, подобном следующему:

this

Однако мой результат больше похож на изображение ниже:

Я не уверен, что я делаю неправильно, вот мой код

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

int main(void){

    int i, status;
    printf( "Enter a value for n :");
    int n;
    scanf("%d", &n);

    FILE *file;
    file = fopen("./digraph.txt", "w+"); //my output file
    fprintf(file, "digraph {\n");
    for (i=0; i<n; i++){

        fflush(file);
        int pid = fork();

        if (pid == 0) {//child

            if(i == 0) { //first level
                fprintf(file, "    \"%d\" [ label=\"pid %d, level %d\" ];\n", getppid(), getppid(), i, file);
                fprintf(file, "    \"%d\" [ label=\"pid %d, level %d\" ];\n", getpid(), getpid(), i +1, file);
                fprintf(file, "    \"%d\" -> \"%d\";\n", getppid(), getpid(), file);
            }else{
                fprintf(file, "    \"%d\" [ label=\"pid %d, level %d\" ];\n", getpid(), getpid(), i , file);
                fprintf(file, "    \"%d\" -> \"%d\";\n", getppid(), getpid(), file);
            }
        }
        else {
            pid = waitpid(-1, &status, 0);
            break;
        }
    }
    if (i>n){
        fprintf(file, "}");
        fclose(file);
    }
}

1 Ответ

1 голос
/ 12 февраля 2020

Как я уже говорил ... Вы только fork() один раз за итерацию из вашего недавно созданного дочернего процесса. То есть вы не можете ожидать древовидного представления, верно?

Чтобы это произошло, вам, вероятно, нужно, чтобы что-то подобное происходило в вашем l oop:

for (i=0; i<n; i++){
    fflush(file);
    pid_l = fork();

    if (pid_l == 0) { //left child
        if(i == 0) { //first level
            fprintf(file, "    \"%d\" [ label=\"pid %d, level %d\" ];\n", getppid(), getppid(), i);
            fprintf(file, "    \"%d\" [ label=\"pid %d, level %d\" ];\n", getpid(), getpid(), i + 1);
            fprintf(file, "    \"%d\" -> \"%d\";\n", getppid(), getpid());
        }else{
            fprintf(file, "    \"%d\" [ label=\"pid %d, level %d\" ];\n", getpid(), getpid(), i + 1);
            fprintf(file, "    \"%d\" -> \"%d\";\n", getppid(), getpid());
        }
        return 0;
    }
    else {
        printf("parent: %d left child: %d\n", getpid(), pid_l);
        pid_r = waitpid(-1, &status, 0);
    }

    pid_r = fork();

    if (pid_r == 0) { //right child
        if(i == 0) { //first level
            fprintf(file, "    \"%d\" [ label=\"pid %d, level %d\" ];\n", getppid(), getppid(), i);
            fprintf(file, "    \"%d\" [ label=\"pid %d, level %d\" ];\n", getpid(), getpid(), i + 1);
            fprintf(file, "    \"%d\" -> \"%d\";\n", getppid(), getpid());
        }else{
            fprintf(file, "    \"%d\" [ label=\"pid %d, level %d\" ];\n", getpid(), getpid(), i + 1);
            fprintf(file, "    \"%d\" -> \"%d\";\n", getppid(), getpid());
        }
    }
    else {
        printf("parent: %d right child: %d\n", getpid(), pid_r);
        pid_r = waitpid(-1, &status, 0);
        break;
    }
}

if (i == n) {
    fprintf(file, "}");
    fclose(file);
}

Итак, подход здесь - вам нужно fork дважды, сразу же вернуться от левого ребенка, продолжить справа как новый родитель.

Еще несколько заметок об изменениях:

  • у вас есть дополнительный аргумент во всех ваших fprintf() вызовах. Просто отбросьте этот последний file аргумент. В этом топи много предупреждений c.
  • Вы неправильно заполняете последнюю скобку в файле точек - замените (i > n) на i == n

При использовании переработанного l oop результат будет выглядеть примерно так:

enter image description here

Что больше похоже на то, что вы хотели.

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