C++ – Multiple child creation with fork() in Linux

c++forklinuxoperating-system

I want to create multiple children using fork(), but I am facing problems.
LIKE:

///////////////////////// these are some class objects creation and calling
//  There are some functions calling from another class. about 5 functions I invoked.
// and some variables like.

    pid_t PID;
    int status = 0;
    char *x = new char[10];

///////////////////////// This for loop give me multiple children
// now one parent have multiple children in this case 10


    for( int i=0; i<10; i++ )
    {
        mNo++;
        rNo++;
        PID = fork();

        if( PID == FORK_ERROR )         // fork ERROR!
        {
            fprintf(stderr, "ERROR! In fork() [FORCE EXITING]... %d\n", errno);
            exit(EXIT_FAILURE);
        }
        else if( PID == CHILD )         // Do Child Stuff Here...
        {
            exit(status);
        }
        else            // Do parent Stuff Here...
        {

        }
    }
    PID = wait(&status);

////////////////////////////////////////////

This was my code which I implemented, but there are some problems.

I want to ask that when I create a child in memory, it creates the duplicate memory . Also the objects which I declared; are they reinvoked by calling fork() so does that mean that for every child there are objects in memory which are reinvoked on class?

I want that if I fork, and the previous functions calling and variables should be same for every child but not non-idempotent functions. I hope you get it. I know this is a very simple problem, but the project I am working on is very critical and it has to implemented with fork(), not in pipes or threads.

Moreover, I am repeating my question that if I fork(), what happens to objects and variables. Before calling fork, are they just reallocated or they again reinvoked for every child? But what I am seeing is that they are reinvoked for every child, which I don't want. So what do I have to do?

Best Solution

The behaviour of fork() will not change to suit your wishes.

When the process forks, there are two almost identical copies of the same program. The differences are listed in the POSIX manual page (link above). The memory is the same. Objects in C++ will not be re-constructed, for example. In each of the processes, all the singletons will still be singletons, for example.

Could you give me an example?

Here's the complete main program from something I wrote back in 1991. I've only updated it to use a prototype for main() and I've included the typedef for Pipe and the definition of id:

static char id[] = "\n\n\nSQLMONITOR version 3.5 \n";
typedef int Pipe[2];

int main(int argc, char **argv)
{
    int     pid;
    Pipe    to_sqlexec;
    Pipe    from_sqlexec;

    setarg0(argv[0]);
    write(STDERR, id, sizeof(id)-1);
    if (pipe(to_sqlexec) < 0 || pipe(from_sqlexec) < 0)
        error("unable to create pipes");
    else if ((pid = fork()) < 0)
        error("unable to fork");
    else if (pid == 0)
        be_childish(argv, to_sqlexec, from_sqlexec);
    else
        be_parental(to_sqlexec, from_sqlexec);
    return(0);
}

The be_childish() function went on to do some plumbing (duplicating and closing appropriate parts of the pipes, before executing another program. The be_parental() process went on to read messages from its standard input, log them to a file, and write the messages to the standard input of its child down the write-side of the to_sqlexec pipe; it would then read a response back from the child on the read-side of the from_sqlexec pipe, and log that message too, and then write it to its standard output. Thus, it would sit in the middle of two processes, recording everything that went from one to the other. The communication protocol between the processes was synchronous, which greatly simplified life. On the other hand, it was moderately hard to work out when the data from one process was complete. The code predated the widespread availability of select() and poll(); nowadays, it would not need to do as much analysis of the messages.

The key thing to note, though, is that the two pipes are the same in both processes after the fork(); indeed, the only variable that's different is pid which captures the return value from fork(). Everything else is exactly as it was before the fork().