Reputation: 35
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
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
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
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:
This is a good way to understand what will happen.
Upvotes: 0
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