Ryan
Ryan

Reputation: 35

Fork tree diagram

Ok so I am going through past papers and I am stuck on a question about fork() function here is the diagram I am supposed to recreate using C.

I understand that fork() returns 0 to the child and the childs PID to the parent, but it's really hard to get my head around how exactly this all works.

I have come up with the following but I don't think it works:

while(fork() == 0) {
  if (fork() == 0) break;
}

Any help would be appreciated.

Upvotes: 2

Views: 1840

Answers (4)

AlexPogue
AlexPogue

Reputation: 777

Debugging your current code:

while(fork() == 0) {

This line creates a child process (we'll call it child process 1). The parent's process does not enter into the while loop. Child process 1 enters the loop.

if (fork() == 0) break;

This line is now being executed by child process 1, forking from it to create child process 2. If we are currently executing child process 2 (the 'child' of this fork call), we break. If we are executing child process 1, we will continue the next iteration of the while loop.

Now we have the following process tree:

    . p
   /
  . child process 1
 /
. cp2

Executing the while loop with child process 1 follows the same pattern as when we passed in parent, resulting in:

    . p
   /
  . child process 1
 /    \
. cp2  . cp3
      /
     . cp4

Solution:

Our end goal is to create 2 child processes, and continue forking from the second child process.

while (1) {
    pid_t c1 = fork();
    assert(c1 >= 0); // check fork error
    if (c1 == 0) break; // don't make more children from c1
    pid_t c2 = fork();
    assert(c2 >= 0);
    if (c2 > 0) break; // don't make additional children from parent
}

Upvotes: 3

Some programmer dude
Some programmer dude

Reputation: 409442

You are on the right track, in that you need to create new processes in a loop. But the way I think that image mean is that you should let the original parent keep creating processes inside an infinite loop, and the child (all siblings) do their work and exits.

There is also a problem with that image, in that a fork call doesn't really create two children, only one child and then the parent continues, which means that "child2` in that image is really all just the "parent".

So to implement something to create that tree I would do something like

for (;;)
{
    int ret = fork();
    if (ret == 0)
    {
        // In the child, "child1" in the image
        // Do whatever is supposed to be done
        exit(0);  // Exit the child
    }
    else if (ret == -1)
    {
        // Error, handle it somehow
    }
    else
    {
        // In parent, what is called "child2" in the image
        // Do something useful here...

        // Then wait for the child to exit
        wait(NULL);
    }

    // Let the loop iterate, to create a new "child1"
}

Upvotes: 0

Jean-Baptiste Yunès
Jean-Baptiste Yunès

Reputation: 36441

Write your code and add boxes for variable values on a sheet of paper and execute it by hand. Each time fork() is called:

  • make a photocopy of your sheet,
  • on the original give some unique non negative value for the return of fork,
  • on the copy give 0 to the returned value of fork,
  • continue to execute instructions on all sheet of paper in any order you want.

This is a good way to understand what will happen.

Upvotes: 0

untitled
untitled

Reputation: 409

If you want to create two children processes from each child2 (and initial parent):

#define MAX 6

int value;
unsigned u = 0;

do{
    if((value = fork()) == 0) // child1
        break;
    else if(value < 0) // error
        break;

    // parent

    if((value = fork()) > 0) // parent
        break;
    else if(value < 0) // error
        break;

    // child2

    u++;
}while(u < MAX);

if you don't want to set a MAX, use while(1).

Your program didn't create child1 for the first parent.

Upvotes: 1

Related Questions