Search code examples
cfork

How to fork only with a specific child?


I am trying to build a process tree like this:

               P1
            /      \
          P3        P2
                      \
                       P4
                        \
                         ....

But i couldn't make it work. I tried this but it only forks with P1.

for(int i = 0; i < depth; i++) {
    int _pid = fork();
    if(_pid == 0) {
        printf("[son] pid %d from [parent] pid %d\n", getpid(), getppid());
        exit(0);
    }
}
wait(NULL);

Solution

  • The requirement to use only one fork call makes the solution cumbersome and ugly, but still doable like this:

    Step 1: create an inner loop that will run twice if i is 0, and once for any i > 0.

    Step 2: fork only in the child process after the first iteration of the outer loop.

    Step 3: exit the child that was forked on the second iteration of the inner loop.

    int cur_pid = 0;
    
    printf("Root PID %d started by %d\n", getpid(), getppid());
    
    for (int i = 0; i < depth && cur_pid == 0; i++) {
        for (int j = 0; j < (i ? 1 : 2); j++) {
            cur_pid = fork();
            if (cur_pid == 0) {
                printf("[son] pid %d from [parent] pid %d\n", getpid(), getppid());
                if (j == 1) {
                    exit(0);
                } else {
                    break;
                }
            } else if (cur_pid < 0) {
                printf("Error forking at PID %d\n", getpid());
            }
        }
    }
    
    wait(NULL);
    

    Remember to wait on the child process of every iteration if you want getppid to return valid values!