How can I use fork () recursively?

I programmed this over and over again and it was hard for me to learn how to work with fork () to recursively generate child processes. I started programming some pretty complicated things, and I decided to start again with something simpler.

I just started to study processes, and I had problems understanding them. The program is intended for branching the process tree, however, I have to redo the two processes from the root, which will be a fork, 3 child processes are processed on the left side, and 4 child processes on the right side. These processes should have the form 3 and 4, respectively, of their own processes.

My problem is that the program can branch processes, however, only one process on each side puts all the children on their respective side.

Any help you could give me would be wonderful, please tell me if I am not clear enough.

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

/* Prototypes */
void three_children();
void four_children();

int main()
{
    pid_t process;
    int status,n;

    printf("Number of levels: \n");
    scanf("%d", &n);
    for (int i = 0; i < n ; i++) {
        process = fork();
        switch (process) {
            case -1:
                printf("Error\n");
                break;
            case 0:
                if (i == 0) {
                    printf("Left\n");
                    three_children(process, status);
                } 
                if (i == 1) {
                    printf("Right\n");
                    three_children(process, status);
                }
                printf("Hi I'm a child PID: %d, my father is PPID: %d\n", getpid(), getppid());
                exit(0);
            default:
                printf("I'm a father PPID: %d\n", getppid());
                break;
        }
    }
}

void four_children(pid_t process, int status)
{
    for (int j = 0; j < 4; j++) {
        process = fork();
        switch (process) {
            case -1:
                printf("Error\n");
                break;
            case 0:
                printf("I'm child: %d, and my father is: %d\n(four children)\n", getpid(), getppid());
                exit(0);
                break;
            default:
                printf("I'm a father process: %d\n", getpid());
                four_children(process, status);
                for (int j = 0; j < 3; j++) {
                    wait(&status);
                }
                break;
        }
    }
}

void three_children(pid_t process, int status)
{
    for (int k = 0; k < 3; k++) {
        process = fork();
        switch (process) {
            case -1:
                printf("Error\n");
                break;
            case 0:
                printf("I'm a child: %d, and my father is: %d\n(three children )\n", getpid(), getppid());
                exit(0);
                break;
            default:
                printf("I'm father %d\n", getpid());
                three_child(process, status);
                for (int j = 0; j < 3; j++) {
                    wait(&status);
                }
                break;
        }
    }
}
+4
source share
1 answer
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
typedef struct Node
{   
    int             childrenCount;
    struct Node*    child[0];
} Node;

Node* makeNode(int children)
{   
    Node* result = (Node*)malloc(sizeof(Node) + sizeof(Node*) * children);
    if (!result) {
        exit(1);
    }   
    result->childrenCount = children;
    for(int loop = 0;loop < children; ++loop) {
        result->child[loop] = NULL;
    }   
    return result;
}   

void buildTree(int indent, pid_t parent, Node* node);
void createChild(int indent, pid_t parent, Node* node, int childIndex)
{   
    pid_t pid = fork();
    if (pid == -1) {
        exit(1);
    }   
    if (pid == 0) {
        buildTree(indent + 1, getpid(), node->child[childIndex]);
        srand(parent * 10  + childIndex);
        exit(rand());
    }   
    for(int ind = 0; ind < indent; ++ind) {
        fprintf(stderr, " ");
    }   
    fprintf(stderr, "Parent: %d Spawned %d\n", parent, pid);
}   

void buildTree(int indent, pid_t parent, Node* node)
{   
    for(int ind = 0; ind < indent; ++ind) {
        fprintf(stderr, " ");
    }   
    fprintf(stderr, "Parent %d Has %d Children\n", parent, node->childrenCount);
    for(int loop = 0; loop < node->childrenCount; ++loop) {
        createChild(indent, parent, node, loop);
    }   
    for(int loop = 0; loop < node->childrenCount; ++loop) {
        int status;
        int child = wait(&status);
        for(int ind = 0; ind < indent; ++ind) {
            fprintf(stderr, " ");
        }
        fprintf(stderr, "Parent: %d Reaped %d with status %d\n", parent, child, status);
    }
}

int main()
{
    Node* root = makeNode(2);
    root->child[0]   = makeNode(3);
    for(int loopChild = 0;loopChild < 3; ++loopChild) {
        root->child[0]->child[loopChild] = makeNode(3);
        for(int loopGrandChild = 0;loopGrandChild < 3; ++loopGrandChild) {
            root->child[0]->child[loopChild]->child[loopGrandChild] = makeNode(0);
        }
    }
    root->child[1]   = makeNode(4);
    for(int loopChild = 0;loopChild < 4; ++loopChild) {
        root->child[1]->child[loopChild] = makeNode(4);
        for(int loopGrandChild = 0;loopGrandChild < 4; ++loopGrandChild) {
            root->child[1]->child[loopChild]->child[loopGrandChild] = makeNode(0);
        }
    }

    fprintf(stderr, "Start\n");
    buildTree(0, getpid(), root);
    fprintf(stderr, "Stop\n");
}
+1
source

Source: https://habr.com/ru/post/1685663/


All Articles