Question
I have a C file that looks like this:
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main ()
{
pid_t child_pid;
printf ("The PID is %d\n", (int) getpid ());
child_pid = fork ();
if (child_pid != 0)
{
printf ("this is the parent process, with PID %d\n",
(int)getpid());
printf ("the child's PID is %d\n", (int) child_pid);
}
else
printf ("this is the child process, with PID %d\n",
(int)getpid());
return 0;
}
I need to modify it to produce a a hierarchy that looks like
parent (0)
|
+---> child (1)
|
+---> child (2)
|
+----> child (3)
|
+----> child (4)
|
+----> child (5)
|
Basically a tree structure where each second child makes two new children. As far as I understand it, when I fork()
a process, each process will run concurrently. Adding a fork()
in the if
statement seems to work and creates processes 0 to 2 correctly, since only the parent will create a new fork. But I have no idea how to make process 2 fork and not 1. Any ideas?
Solution
Well, process 1 will be created by the first fork. Process 2 will be created by the fork inside the if-statement. So to let process 2 fork too, you fork again inside the if-statement if the second fork did not return 0.
An illustration:
if(fork) {
// Inside process 0
if(fork) {
// still in process 0
} else {
// in process 2
if(fork) {
// still in process 2
} else {
// in prcess 3
}
// and so on
}
} else {
// Inside process 1
}
OTHER TIPS
Children get a copy of the parent's state at the time of the fork.
So if the parent has a counter or other property then the children will see the value at the time of they were forked (but not if the parent subsequently alters it).
I don't know why you want to do it this way, but normally only the parent process performs the fork. This may be easier to design too. When you perform fork() inside a for-loop you'll have direct control over the processes created.
Please be aware that fork() is a relatively expensive operation, especially if you want to create many processes. More lightweight alternatives vfork and threads are available but I can not judge if they also fit your needs.
An old question, but an interesting one still. The man page for fork()
tells us that the return value:
On success, the PID of the child process is returned in the parent, and 0 is returned in the child. On failure, -1 is returned in the parent, no child process is created, and errno is set appropriately.
So we know that fork()
returns a 0 to the child, we can use this as the controlling mechanism:
int main()
{
// Here we're in the parent (0) process
if(fork()) // This starts the chain, only the parent will do this
if(!fork()) //the child will pass this, the parent will skip it
for(count = 0; counter < number_of_processes; counter++) //now the 2nd child loops
{
if(fork())
if(!fork());
else
break;
}
Let's put some numbers to it:
//parent (18402)
if(fork()) // spawns 18403, parent 18402 keeps going
if(!fork()) // spawns 18404, parent 18402 drops to the end of main()
for(count = 0; count < number_of_processes; conter++) // 18404 enters here
if(fork()) // 18404 forks 18405 and then goes on
if(!fork()); // 18404 spawns 18406 before leaving, 18406 restarts the loop
else
break; // 18404 breaks out there
else
break; //18405 leaves the loop here
So after one iteration we have:
18402
|
+---> 18403
|
+---> 18404
|
+----> 18405
|
+----> 18406
|
After this we'll keep looping two new processes, the second of which will keep iterating until you've made as many passes as are required.