Urban
Urban

Reputation: 2199

Problem creating multiple child processes

Im new at process creation etc..so probably a basic question.
Im creating a fixed number of child processes, each doing nothing but printing their pid. The problem is in the output that i get. Have a look:

int main(){  
pid_t pid=0;  
int i=0,status=0;

    for(i=0;i<3;i++){
            pid=fork();
            switch(pid){
                    case 0:{        //Child
                            printf("\nChild pid: %d",getpid());
                            exit(0);
                            break;
                            }
                    case -1: {//Error
                            printf("Error occured in fork");
                            exit(1);
                            break;
                            }
                    default:{
                            printf("\nParent id: %d",getpid());
                            printf("\nIts child id: %d",pid);
                            wait(NULL);
                            }
            }

Output:
Child pid: 1450
Parent id: 1445
Its child id: 1450
Child pid: 1455Its child id: 1450
Parent id: 1445
Its child id: 1455
Child pid: 1460Its child id: 1455
Parent id: 1445
Its child id: 1460

The problem is I dont know why only the second print statement of the parent process is appearing and not the first, if any at all. I know im not waiting for my child processes to end( frankly i dont know how i would do that), but if the parent does execute before ending its child processes, why arent both its print statements appearing, and why is the \n being ignored in that line too.
Any help would be greatly appreciated.
Thx.

Update:If i replace wait(NULL) with printf("\n%d\n",wait(NULL)) It gives me a perfect output, without stray prints. Any idea what couldve fixed it? After all they both do the same thing.

Upvotes: 0

Views: 1306

Answers (2)

rodrigo
rodrigo

Reputation: 98496

The problem is that there are several processes writing to the same file (your console) at the same time without any concurrency control or any lock. That, and that the ttys are strange creatures, at best, make weird things happens. Over that, remember that printf is buffered.

Your output should be read this way:

Child pid: 1450    <- Child #1
Parent id: 1445    <- Parent #1.1
Its child id: 1450 <- Parent #1.2

Child pid: 1455[Its child id: 1450] <- Child #2 with garbage at the end
Parent id: 1445                     <- Parent #2.1
Its child id: 1455                  <- Parent #2.2

Child pid: 1460[Its child id: 1455] <- Child #3 with garbage at the end
Parent id: 1445                     <- Parent #3.2
Its child id: 1460                  <- Parent #3.2

You could try redirecting the output to a file, and see if not being a tty makes any difference.

Anyway, to do it the right wat, you should use any mechanism that guarantees multiprocess correctness.

UPDATE

Yes, now I see it. You have the '\n' at the beginning of your printing lines, not at the end, as is usual. Stdout is normally line-buffered, that means that the buffer is flushed to the device when it sees a '\n'. And since you have them at the beginning there is always one line in the buffer waiting for output.

Now, when you fork your process the output buffer gets duplicated and the last line from the parent is printed by the child (why it is printed after, and not before, is still a mystery to me).

Anyway, the new printf you added has a '\n' at the end, so it flushes the buffer, fork finds it empty and all goes fine. You could as well call fflush(stdout) but it is cumbersome.

The morale of the story is: "When you printf for debugging purposes always put a \n at the end of every line or you can get partial, mixed contents.

Upvotes: 1

Soren
Soren

Reputation: 14718

The problem is buffering and flushing of stdout.

Both lines are being printed, but not flushed to output at the time you expect.... depening on where the output is going to, (file, pipe, terminal, stderr etc) printf uses different buffer strategies.

I guess that in your case it only flushes on newline (check man setbuf)

Move the newline to the end of the rather than in the beginning, so for example....

       printf("Parent id: %d\n",getpid());
       printf("Its child id: %d\n",pid);

And be consistent with alway putting the \n at the end of printf for all your printfs.

Upvotes: 0

Related Questions