Alex Goft
Alex Goft

Reputation: 1124

Trouble understanding fork() output

Let's assume that there is a process with PID = 1 and it runs the following code:

int a = fork();
int b = fork();
printf(“a: %d, b: %d\n”, a, b); 

Let's further assume that new PIDs will be given one by one, so the second given PID will be 2, then 3 etc.

A possible output is:

a:2, b:3
a:2, b:0
a:0, b:4
a:0, b:0

I'm having some troubles trying to understand the output of the above code, e especially why a:0, b:4 and a:2, b:3.

Upvotes: 4

Views: 391

Answers (5)

rpadovani
rpadovani

Reputation: 7360

You know that

The return value is the zero in the child and the process-id number of the child in the parent, or -1 upon error.

So, let's see step by step what's happening here.

When fork() is called, it creates a new child with id n, then returns in the child 0 and in the parent n.

So let's suppose our process as pid 1, when the first fork() is called it creates a process with pid 2, then returns to a a value. a will have value 0 in the process 2 (the child), and will have value 2 in process 1 (the parent).

Then each process will call fork() and assign the return value to b in the parent process. In the child, b will have value 0.

Anyway, I think this schema will simplify the comprehension:

The main starts:

|
|
int a = fork(); // It creates a new process, and the old one continues going
|
|-------------------------|
a = 2; /* Parent */       a = 0; // Child
|                         |
|                         |
int b = fork();           int b = fork(); // Each one create a new process
|                         |
|                         |-----------------------------|
|                         /* Child -> Parent */         // Child -> Child
|                         a = 0; b = 4;                 a = 0; b = 0
|
|
|
|
|-----------------------------|
/* Parent -> Parent */        // Parent -> Child
a = 2; b = 3;                 a = 2, b = 0; 

Upvotes: 13

xenteros
xenteros

Reputation: 15842

I'm not even trying to answer your question. It's more about showing the pattern which is commonly used. It might have been a comment if only there was proper code formatting in comments.

The basic construction with fork() is:

if (int PID = fork() == 0 ) {
    //it's a child process
} else {
    //it's a parent process
}

Using simple

int PID1 = fork();
int PID2 = fork();

is very risky as you will almost for sure receive Race condition.

Upvotes: 4

sps
sps

Reputation: 2720

Original process:
forks child A, and child B
prints `a:2, b:3`

    child A process:
    forks child BB
    prints `a:0, b:4`

        child BB proess:
        forks nothing
        prints `a:0, b:0`

    child B process:
    forks nothing
    prints `a:2, b:0`

And since you have not use any wait or waitpid these can appear in any order.

Upvotes: 0

blatinox
blatinox

Reputation: 843

After a fork, you can be either in the father (fork returns the child's PID) or in the child (fork returns 0).

After the first call to fork, you will have 2 processes: the father (a = 2 in your example) and the child (a = 0).

Both will fork, the father (a = 2) will give a child (b = 0) and a new father (b = 3). The child (a = 0) will give a new child (b = 0) of which it will be the father (b = 4).

Your possible output is:

a:2, b:3 -> father and father
a:2, b:0 -> father and child
a:0, b:4 -> child and father
a:0, b:0 -> child and child

Upvotes: 1

user703016
user703016

Reputation: 37945

Before first fork:

PID 1 (father)
a = (not in scope yet)
b = (not in scope yet)

After first fork:

PID 1 (father)
a = 2
b = (not in scope yet)

PID 2 (child of 1)
a = 0
b = (not in scope yet)

After second fork:

PID 1 (father)
a = 2
b = 3

PID 2 (child of 1)
a = 0
b = 4

PID 3 (child of 1)
a = 2
b = 0

PID 4 (child of 2)
a = 0
b = 0

Upvotes: 4

Related Questions