So I have this function that forks N number of child processes. However it seems to be forking more than specified. Can you tell me what I\'m doing wrong? Thanks
Each child process picks up and continues the loop.
In other words, child 1 is spawned and continues with iteration #2 of loop etc.
When a process is forked, a copy of the current process is made: the resulting child process continues execution after the fork() call. That's why you must take care of the return code in your logic.
In this exercise I'd use recursion rather than a for loop. This way you can have the fork() instruction called multiple times but just on one of the two copies of the process. You can make the child process spawn another child process, thus having grandparents, grand-grandparents etc. or you can call the fork() on the parent side, having a single "father" and multiple children. This is a sample of code which implements the latter solution:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int nChildren;
void myFork(int n);
int main(int argc, char *argv[]) {
// just a check on the number of arguments supplied
if (argc < 2) {
printf("Usage: forktest <number_of_children>\n");
printf("Example: forktest 5 - spawns 5 children processes\n");
return -1;
}
nChildren = atoi(argv[1]);
// starting the recursion...
myFork(nChildren-1);
return 0;
}
// the recursive function
void myFork(int n) {
pid_t pid;
pid = fork();
// the child does nothing but printing a message on screen
if (pid == 0) {
printf("I am a child: %d PID: %d\n", nChildren-n, getpid());
return;
}
// if pid != 0, we're in the parent
// let's print a message showing that the parent pid is always the same...
printf("It's always me (PID %d) spawning a new child (PID %d)\n", getpid(), pid);
// ...and wait for the child to terminate.
wait(pid);
// let's call ourself again, decreasing the counter, until it reaches 0.
if (n > 0) {
myFork(n-1);
}
}
The fork() call spawns a new process which begins its execution at the exact same point where the fork occurred. So, it looks like fork "returns twice"
What's happening here is that your fork() call returns twice, so both the parent and child process continue looping and spawning new processes. Each child (of both the original parent and child) then forks again, repeatedly doubling the number of processes...
When you fork
a process, you basically end up with two (almost) exact copies of the process and both of them will continue running.
So what's happening is that the children themselves are continuing the loop in the own process space (after they print their output) as well as the parent doing it. And, in fact, because these children are also forking, the grandchildren will also carry on from that point. I'm sure there's a formula for actually figuring out how many children you end up with (probably something like N!) but I don't have the energy to figure it out at the moment. Better to use the following solution.
The way to tell the difference between parent and child is the return value from fork
.
fork
failed.wait
for it).Here's some test code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void forkChildren (int nChildren) {
int i;
pid_t pid;
for (i = 1; i <= nChildren; i++) {
pid = fork();
if (pid == -1) {
/* error handling here, if needed */
return;
}
if (pid == 0) {
printf("I am a child: %d PID: %d\n",i, getpid());
sleep (5);
return;
}
}
}
int main (int argc, char *argv[]) {
if (argc < 2) {
forkChildren (2);
} else {
forkChildren (atoi (argv[1]));
}
return 0;
}
and some output to show you what's happening:
pax> forktest 5
I am a child: 1 PID: 4188
I am a child: 2 PID: 4180
I am a child: 3 PID: 5396
I am a child: 4 PID: 4316
I am a child: 5 PID: 4260
pax> _