Yes. There is a caveat though, the child processes will need to exit from the case statement, otherwise it will fall into the loop it inherited from it's parents and fork it's own children, etc (leading to grandchildren, etc). This could eat up resources very quickly.
Try the following code as proof. I compiled it with gcc as "gcc -Wall fork.c -o foobar". Then, I ran it as "./foobar 3", and for extra proof, in a second terminal window I ran "ps -ef | grep foobar" while foobar was still running.
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <errno.h>
int main(int argc, char *argv[])
{
int i,
x = 0,
pid,
nap_time;
if (argc != 2) {
printf("Missing command line option\n");
return 1;
}
x = atoi(argv[1]);
if (x == 0) {
printf("Need a numeric command line option\n");
return 1;
}
for (i = 0; i < x; i++) {
pid = fork();
switch (pid) {
case -1:
// error
fprintf(stderr, "fork failed: %s\n", strerror(errno));
break;
case 0:
// act childish
srand(getpid());
nap_time = rand() % 5 + 2;
printf("Child %i going to sleep for %d seconds\n", i, nap_time);
sleep(nap_time);
printf("Child %i waking up\n", i);
return 0; // If you just did break, you would get 1 + 2 + ... + x child processes
default:
// record child's pid if needed for checking signals later
break;
}
}
sleep(10);
return 0;
}
$ ps -ef | grep foobar
anduril462 5860 5539 0 16:05 pts/2 00:00:00 ./foobar 3
anduril462 5861 5860 0 16:05 pts/2 00:00:00 ./foobar 3
anduril462 5862 5860 0 16:05 pts/2 00:00:00 ./foobar 3
anduril462 5863 5860 0 16:05 pts/2 00:00:00 ./foobar 3
anduril462 5865 5813 0 16:05 pts/1 00:00:00 grep foobar