I was trying to create n
(say n=3
) child processes from a single parent process but couldn't reach a solution. I have tried this code:
for(i=0; i<3; i )
{
fork();
}
But unfortunately it is creating 7 child processes.
CodePudding user response:
This happens because each of the children continues executing the loop from where it was when it forked:
- The root process forks 3 children:
a
,b
,c
a
seesi=0
and creates childrend
ande
d
seesi=1
and createsf
b
seesi=1
and createsg
c
,e
,f
andg
seei=2
and just exit the loop.
That makes 7 children. You need to check the return value of fork()
to make sure that you're in the parent process:
if (!fork()) { // returns 0 to the child
break;
}
CodePudding user response:
You will have to put a check so that only parent could create child processes, here is the example to do it:
pid_t pid1;
pid1 = getpid();
for(i = 0; i < 3; i )
if(pid1 == getpid())
fork();
CodePudding user response:
You need first to consider that all those forks return both in the parent and the child, so they all create three processes in a three level binary tree (leading to seven final processes)
The right way to do is to check the parent's return value, which is:
-1
in case of error (you must always check) you need to checkerrno
to get an idea of why thefork()
failed.0
in this case you are the child, you have not tofork()
again, or you will end with lots of processes. I just pause for 10 seconds, then die in the sample code below.> 0
to allow the parent to know the child's pid (and save it to know which of the childrenexit()
ed on eachwait()
return). (you are the parent process)
this leads to some code like this:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
int main()
{
int i;
for (i = 0; i < 5; i ) { /* repeat five times */
int child_pid;
if ((child_pid = fork()) < 0) { /* error */
perror("fork");
exit(1);
} else if (child_pid > 0) { /* we are the parent */
printf("Parent, forked child %d with pid = %d\n",
i, child_pid);
/* we continue with the next child until no more
* children to start, then we will wait(2) for them
* all, before exiting. */
} else { /* we are the child */
/* our pid is got from getpid(2) system call */
printf("I'm the %d child, with pid = %d\n",
i, getpid());
sleep(10); /* do something useful, like sleeping :) */
exit(0); /* and exit */
}
/* the only process that gets here is the parent, as the child
* does an exit in its block above */
/* go for next child */
}
printf("... now, we need to wait until no children are alive\n");
int child_exit_pid;
while ((child_exit_pid = wait(NULL)) >= 0) { /* wait until we get an error */
printf("Child with pid == %d exit\n",
child_exit_pid);
}
printf("Parent exit after all children died\n");
}