'How to fork multiple processes from a same parent?

I am trying to create multiple processes from a same parent, but it always ended up with more processes than expected. I couldn't figure out how to do it and need some help here.

I found a piece of code online and tried it,

int main ()
{
    pid_t pid=0;
    int i=0;
    for (i=0; i<3; i++)
    {
        pid=fork();
        switch(pid)
        {
            case 0:
            {
                cout<<"\nI am a child and my pid is:"<<getpid();
                cout<<endl;
                exit(0);
                break;
            }
            default:
            {
                cout<<"\nI am a parent and my pid is: "<<getpid();
                cout<<"\nMy child pid is: "<<pid;
                cout<<endl;
                wait(NULL);
                break;
            }
        }
    }
  return 0;
 }

This code does work and creates 3 children from same parent. However, it seems like that's because after each child process was created, it was terminated immediately. So it won't fork more grandchild process in the next round of for loop. But I need to keep these child processes running for sometime and they need to communicate with the parents.



Solution 1:[1]

A child process may immediately break the loop to continue its work outside

int main ()
{
   cout<<"\nI am a parent and my pid is: "<<getpid()<<endl;

   pid_t pid;
   int i;
   for (i=0; i<3; i++)
   {
       pid=fork();
       if(pid == -1)
       {
           cout<<"Error in fork()"<<endl;
           return 1;
       }
       if(pid == 0)
           break;
       cout<<"My child "<<i<<" pid is: "<<pid<<endl;
    }

    if(pid == 0)
    {
        cout<<"I am a child  "<<i<<" and my pid is "<<getpid()<<endl;
        wait(NULL);  // EDIT: this line is wrong!
    }
    else
    {
        cout<<"I am a parent :)"<<endl;
        wait(NULL);  // EDIT: this line is wrong!
    }
    return 0;
}

EDIT
The wait(NULL) lines are wrong. If the process has no children active, wait() has no effect, so it's useless in children here. OTOH in the parent process wait() suspends the execution until any of children exits. We have three children here, so would have to wait() three times. Additionally one can't know in advance the order of children completion, so we would need much more sophisticated code for that. Something like this:

struct WORK_DESCRIPTION {
    int    childpid;
    // any other data - what a child has to do
} work[3];

for(i=1; i<3; i++) {
    pid=fork();
    ...
    work[i].childpid = pid;
}

if(pid == 0)    // in a child
{
    do_something( work[i] );
}
else
{
    int childpid;
    while(childpid = wait(NULL), childpid != 0)
    {
        // a child terminated - find out which one it was

        for(i=0; i<3; i++)
            if(work[i].childpid == childpid)
            {
                // use the i-th child results here
            }
    }
    // wait returned 0 - no more children to wait for
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1