Question

I am new to UNIX programming and i was reading about zombie processes and how to avoid them using fork() twice. I read the code from a book and tried to run it on my system.. I am using ubuntu 12.04. I ran the following code:

#include<stdio.h>   
#include<sys/wait.h>
#include<stdlib.h>

int main()
{
    pid_t pid;
    if(pid = fork() < 0)
        printf("Fork Error.!!!\n");
    else 
    if(pid == 0)
    {
        if((pid = fork()) < 0)
             printf("Fork2 Error.!!!\n");
        else 
             if(pid > 0)
                   exit(0);

        sleep(2);
        printf("Second Child, parent id: %d\n", getppid());
        exit(0);
    }
    if(waitpid(pid, NULL, 0) != pid)
        printf("Waitpid Error.!!!\n");

    exit(0);
}

The output that i get is as follows:

Second Child, parent id: 1
Second Child, parent id: 1

The book says this should be printed only once and that is also what i feel should happen when i see what's happening in the code. I dont understand why its getting printed twice. I found this code at many places on the net but could not get something that explains this. Any help is welcome. Thanks.!!

Was it helpful?

Solution

second line of the code in main - missing brackets around pid = fork()

if( ( pid = fork() ) < 0){

OTHER TIPS

In this line:

if(pid = fork() < 0)

you should add parentheses around the pid = fork() part, like you did for the other fork. You are assigning the result of fork() < 0 to pid. As long as the fork didn't fail, that means pid is becoming 0 in both the parent and the child of the first fork, so you're getting 2 processes running the child branch (each one creating a child of its own) and none running the waitpid.

Please check this link. It says:

There are a few differences between exit() and _exit() that become significant when fork(), and especially vfork(), is used.

...

In the child branch of a fork(), it is normally incorrect to use exit(), because that can lead to stdio buffers being flushed twice, and temporary files being unexpectedly removed.

This makes sense to me, and you need to update the code accordingly to get the results as expected.

In

pid_t pid;
if(pid = fork() < 0)
printf("Fork Error.!!!\n");

a thread will be created. So currently we have two threads main thread and child thread. In line

if(pid == 0)

you are checking the current thread in child thread. Again you created a new thread in line

if((pid = fork()) < 0)
     printf("Fork2 Error.!!!\n");
else if(pid > 0)        //Do nothing if this is parent thread.
     exit(0);

So now you have tho threads running and it will execute

printf("Second Child, parent id: %d\n", getppid());

So you are getting the message printed twice.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top