Zakery Alexander Fyke Zakery Alexander Fyke - 1 month ago 18
C Question

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?

Answer

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