Reputation: 165
I have this example of code, but I don't understand why this code creates 5 processes plus the original. (6 process total)
#include <unistd.h>
int main(void) {
int i;
for (i = 0; i < 3; i++) {
if (fork() && (i == 1)) {
break;
}
}
}
Upvotes: 14
Views: 5982
Reputation: 2479
If your main process have pid A, and B - F are subprocesses pids, then:
A spawns B i=0
A spawns C i=1
C run from 'fork' i=1
C spawns D i=2
B run from 'fork' i=0
B spawns E i=1
D run from 'fork' i=2
E run from 'fork' i=1
E spawns F i=2
F run from 'fork' i=2
Where i
is the value of i
of the (sub)process' context.
Since fork
creates an exact copy of the running process, the variable i
will also be copied. When A spawns B, i
is 0. When A spawns C, i
is 1 . Process A now exits the for-loop since i == 1.
Now, subprocess C starts to run, with i
== 1. Note that it will not break inside the for-loop since fork(), at C's spawning point, returns 0. Instead it will loop, increasing i
to 2, spawn D, and exit because of the for-loop's condition.
The subprocess B have i
== 0, when it starts. It spawn subprocess E, and breaks inside the for-loop. (i == 1)
And so on...
When you are tyring to find out of thing like these, I can give you an advice:
Make intermediate variables and print them.
I modified your code, so that it prints out the things I just described:
#include <unistd.h>
#include <stdio.h>
int main(void) {
int i;
for (i= 0; i < 3; ++i) {
int f = fork();
printf("%i\tspawns\t%i\ti=%i\n", getpid(), f, i);
if (f && (i == 1))
break;
}
getchar();
}
Upvotes: 12
Reputation: 659
In the parent process, fork() returns the PID of the child process, and in the child process, it returns 0. With this in mind, look at each iteration of the for loop: (Let's say for simplicity's sake that the PID of the original process is 1)
Upvotes: 6
Reputation: 22125
fork()
splits a process in two, and returns either 0 (if this process is the child), or the PID of the child (if this process is the parent). So, this line:
if (fork() && (i == 1)) break;
Says "if this is the parent process, and this is the second time through the loop, break out of the loop". This means the loop runs like this:
i == 0
: The first time through the loop, i
is 0, we create two processes, both entering the loop at i == 1
. Total now two processes
i == 1
: Both of those processes fork, but two of them do not continue to iterate because of the if (fork() && (i == 1)) break;
line (the two that don't continue are both of the parents in the fork calls). Total now four processes, but only two of those are continuing to loop.
i == 2
: Now, the two that continue the loop both fork, resulting in 6 processes.
i == 3
: All 6 processes exit the loop (since i < 3 == false
, there is no more looping)
Upvotes: 30
Reputation: 3216
First we have one process. Consider the iterations of the loop:
i = 0
The first process calls fork. Now we have 2 processes.
i = 1
The two processes calls fork. Now we have 4.
Fork returns 0 in the newly created processes: Two processes will break from the loop and two will continue in the loop.
i = 2
The two remaining processes calls fork. We get 2 new processes (totaling 6).
Upvotes: 3
Reputation: 96258
I can count six processes (X) here:
i=0 fork()
/ \
i=1 fork() fork()
/ \>0 / \>0
| X break | X break
i=2 fork() fork()
/ \ / \
X X X X
Upvotes: 5
Reputation: 5456
the loop run from i==0
to i==2
.
In the first iterate, the original process (p0) create another one (p1)
In the second iterate, p0
and p1
create one new process each (p2 and p3), and break (Since i==1
and fork
return a non-zero value to the father).
In the third iterate, p2
and p3
create one new process each (p4 and p5).
So, at last, you got 5 new processes.
Upvotes: 3
Reputation: 816
In the children processes the cycle continues to iterate. So they produce new processes too.
Upvotes: 2