Search code examples
cforkwait

Fork() Child Chain


I have the following code, which creates the defined number of child threads using fork():

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

#define NUM_THREADS     4

int main()
{
        int i;
        pid_t pid;
        for(i = 0; i < NUM_THREADS; i++){ //Do this equal to the number of threads
            pid = fork();//Use this to avoid multiple forking

            if(pid == 0){ //If it's a child process
                    printf("Hello World! Greetings from PID: %ld! :D\n", (long)getpid()); //getpid returns the pid of the process
                    exit(0); //Exit the process
            }else if(pid == -1){
                    printf("Oh no! Could not fork! :( Exiting!\n");
                    return 0;
            }
    }
    int status;
    for(i = 0; i < NUM_THREADS; i++){
            wait(&status);//wait until all the children processes have finished.
    }
    printf("All done! I am the parent process! My PID is: %ld if you were curious! \n", (long)getpid());

    return 0;

}

This was provided to us as an example. Its output is like:

Hello World! Greetings from PID: 118358! :D
Hello World! Greetings from PID: 118359! :D
Hello World! Greetings from PID: 118360! :D
Hello World! Greetings from PID: 118362! :D

What I'd like to do, instead of having 1 parent process with many children, is to have the parent create a child process, which creates a child process, and so on for the defined number of threads. How can I do that?


Solution

  • First, the term "thread" you used is inappropriate in this situation. Fork means "creating process" not "threads".

    You can use a recursive solution but you have to remember that each process creating a process should wait for the return status in order to avoid Zombie Process. Without using any shared variable between process you can use a single variable counter that gets incremented for each forking. But once the counter variable reached the max value, the "youngest" process, i mean the last process created should exit, and one by one other process will exit.

    Here is a simple code that works fine:

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    
    #define NUM_PROCESS 5
    
    int counter = 0;
    
    void child_func() 
    {
        pid_t pid;
    
        if (counter < NUM_PROCESS) {
    
            counter++;
    
            pid = fork();
    
            if (pid < 0) {
    
                printf("fork failed counter = %d\n", counter);
    
            }
            else if (pid == 0) {
    
                printf("Hello world ! Greetings from pid %ld\n", (long)getpid());
    
                if (counter == NUM_PROCESS) {
                    exit(0);
                }
                else {
                    child_func();
                }
            }
            else {
    
                long var  = pid;
    
                wait(&pid);
    
                printf("My pid is %ld and i am the parent of %ld child, i exit\n", (long)getpid(), var);
    
                exit(0);
            }   
        }
    }
    
    int main(void) 
    {
    
        pid_t pid;
    
        pid = fork();
    
        if (pid < 0) {
    
            printf("Fork failed %d\n", counter);
    
            return -1;
        }
    
        if (pid == 0) {
    
            child_func();
        }
        else {
    
            wait(&pid);
        }
    
        return 0;
    }
    

    See output