Дерево процессов Linux с использованием fork () - PullRequest
1 голос
/ 03 мая 2019

Я пытаюсь создать следующее дерево процессов с помощью функции fork (): enter image description here

Мне известно, что код немного запутан, но я новичок и не могу многое понять о процессах, хотя и пытался. Я жду несколько советов для кода и какое мнение, является ли этот код правильным или нет. Заранее спасибо.

Ответы [ 2 ]

2 голосов
/ 03 мая 2019

Вы можете разбить задачу на примитивные шаги:

  1. Напишите функцию, которая создает один дочерний процесс, который выполняет предоставленную вами функцию.
  2. Повторно используйте функцию для создания необходимого дерева процессов.

Пример:

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

int level = 1;
char const offsets[] = "\t\t\t\t\t\t\t\t";

pid_t create_child_process(int(*child_fn)()) {
    // Flush the output buffers to avoid duplicate output from the child process.
    fflush(stdout);
    fflush(stderr);

    pid_t child_pid = fork();
    switch(child_pid) {
    case 0: // Child process.
        ++level;
        exit(child_fn());
    case -1: // fork() failed.
        abort();
    default: // Parent process.
        printf("%.*s %u spawned %u\n", level, offsets, (unsigned)getpid(), (unsigned)child_pid);
        return child_pid;
    }
}

void wait_for_any_child() {
    int wstatus;
    pid_t child_pid = wait(&wstatus);
    if(child_pid == -1)
        abort();
    printf("%.*s %u terminated\n", level, offsets, (unsigned)child_pid);
}

int p2() { return 0; }
int p5() { return 0; }
int p6() { return 0; }
int p7() { return 0; }

int p4() {
    create_child_process(p5);
    create_child_process(p6);
    create_child_process(p7);
    wait_for_any_child();
    wait_for_any_child();
    wait_for_any_child();
    return 0;
}
int p3() {
    create_child_process(p4);
    wait_for_any_child();
    return 0;
}

int p1() {
    printf("%u started\n", (unsigned)getpid());
    create_child_process(p2);
    create_child_process(p3);
    wait_for_any_child();
    wait_for_any_child();
    printf("%u terminated\n", (unsigned)getpid());
    return 0;
}

int main() {
    return p1();
}

Выход:

5962 started
     5962 spawned 5963
     5962 spawned 5964
     5963 terminated
         5964 spawned 5965
             5965 spawned 5966
             5965 spawned 5967
             5965 spawned 5968
             5966 terminated
             5967 terminated
             5968 terminated
         5965 terminated
     5964 terminated
5962 terminated
1 голос
/ 03 мая 2019

Это может быть менее беспорядочным, если вы используете собственную переменную pid для каждого pid (например, p1, p2 ...).И, возможно, это поможет, если вы прокомментируете, какой процесс запускает ветки:

pid_t p1, p2, p3, p4, p5, p6, p7;

p1 = getpid(); 
p2 = fork();
if (p2 != 0)    
{
    // P1 runs this branch
    p3 = fork();
    if (p3 == 0)
    {
       // P3 runs this branch
        p4 = fork();
        if (p4 == 0)
        {
            // P4 runs this branch
            p5 = fork();
            if (p5 != 0)
            {
                // P4 runs this branch
                p6 = fork();        
                if (p6 != 0)
                {
                    // P4 runs this branch
                    p7 = fork();        
                }           
            }
        }     
    }
}

В вашем коде могут быть другие проблемы.Но, например, это:

           // create child#1
           fork();

           // create child#2
           fork();

           // create child#3
           fork();

... породит дерево из 7 детей.

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

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