Question

what I need is to have 3 children and 1 parent (the main program) because the children and parent are going to have diferent functionality. I don't know why I can't do it properly, as far I have read, when you do a fork(), if it returns 0, you execute the child's code and the parent's code otherwise. So, this is my program:

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>

int
main(int argc, char ** argv) {

   printf ("Init Parent. PID =%d\n", getpid());

   fork();
   fork();
   if (fork() == 0) {
   printf ("Init Child. PID =%d\n", getpid());
    sleep(1);

   } else {        
    printf ("I am the parent. PID = %d\n",getpid()); 
    sleep(1);

   }
    exit(0);
}

This is the output:

Init Parent. PID =9007
I am the parent. PID = 9007
I am the parent. PID = 9009
Init Child. PID =9010
Init Child. PID =9011
I am the parent. PID = 9008
I am the parent. PID = 9012
Init Child. PID =9013
Init Child. PID =9014

And this is what I want:

Init Parent. PID =9007
I am the parent. PID = 9007
Init Child. PID =9010
Init Child. PID =9011
Init Child. PID =9013
Init Child. PID =9014

I don't know why it says I am the parent 3 times and how to do it properly, because 1

if (fork() == 0) 

seems bad.

I would really appreciate any help, thank you in advance.

Était-ce utile?

La solution

You have to check for parent-child starting from after your first fork. Every time you call fork() you are spawning a child. What you are doing now is this:

  • Starting executing 1 program (+1 proc, 1 proc total)
  • First fork(): Main program spawns child (+1 proc, 2 procs total)
  • Second fork(): Child and main program spawn children. (+2 procs, 4 procs total)
  • Third fork(): All processes previously mentioned spawn children(+4 procs, 8 procs total).

The resulting process tree from your original code would look like this:

      pi
    /  |  \
   pi  pi  pi
  / |  |  
 pi pi pi
 |
 pi

Possible solution(works for n-children):

int noProcs = 3;
int i;
for (i = 0; i < noProcs; ++i) {
  if (fork() == 0) {
    printf("in child\n");
    //Do stuff...
    exit(0);
   }
 }
 //DONT FORGET: Reap zombies using wait()/waitpid()/SIGCHLD etc...

Note that after every fork() call, the children spawned are executing the same subsequent code. For each step in the loop's iteration, here's what happens after I spawn a child with fork():

  • Child process: executes child code, and calls exit(). This prevents us from looping and creating more children than intended.
  • Parent process: Bypasses the if(fork() == 0) statement's body and steps through the loop, spawning additional children as specified.

Autres conseils

fork duplicates the process that calls it, creating a new (child) process that is in the exact same state and that continues running at the same point. The only difference between the parent and child is what is returned by the fork call.

So consider what happens with your code. You start with one process:

printf ("Init Parent. PID =%d\n", getpid());

so that one process prints a message

fork();

you fork, so now have two processes (parent and child)

fork();

both processes fork, so you now have 4 processes (parent, 2 children and grandchild)

if (fork() == 0) {

fork again, so you now have 8 processes -- parent, 3 children, 3 grandchildren, and a great-grandchild. Half of them (one child, two grandchildren, and the great-grandchild) have a 0 return from this fork, as they were the children created by this third fork. The other half are parents.

So after these 3 forks, you have 8 processes, 4 of which will print "Init Child" and 4 of which will print "I am the parent"

If you want just 3 direct children (and no grandchildren), you need to arrange your code such that the children do no call fork again. You could use something like:

if (fork() && fork() && fork())
    printf ("I am the parent. PID = %d\n",getpid());
else
    printf ("Init Child. PID =%d\n", getpid());

Change the code as below.

You need to check on every fork() its return code and not only on the last call of fork. I didn't run and try but this is the error I feel. You said - you need 1 Parent and 3 child - so during first fork() - 1 child will be created and then for second fork() - 1 grandchild of child and 1 more child of a parent will be created.

EDIT:

      parent
       /   \  
   fork-1  fork-2
      |      |
    child1  child-2
      |
    fork-2
      |
    child3 


for(int i=0;i<2;i++)
{
   if (fork()==0)
      printf ("Init Child. PID =%d\n", getpid());
      sleep(1);
   } else {
      printf ("I am the parent. PID = %d\n",getpid()); 
      sleep(1);
   }
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top