parent called more times - fork - C language

Hi gurus can you explain following lines of code ?

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

int main(void)
{
    pid_t pid;
    int rv;

    switch(pid = fork()) {
    case -1:
        perror("fork");  /* something went wrong */
        exit(1);         /* parent exits */

    case 0:
        printf(" CHILD: This is the child process!\n");
        printf(" CHILD: My PID is %d\n", getpid());
        printf(" CHILD: My parent's PID is %d\n", getppid());
    printf(" CHILD: I am sleeping for 15 seconds\n");
        sleep(15);           // exits as a second
    printf(" CHILD: Sleeping is over\n");
    


    default:
        printf("PARENT: This is the parent process!\n");
        printf("PARENT: My PID is %d\n", getpid());
        printf("PARENT: My child's PID is %d\n", pid);
    printf("PARENT: I am sleeping for 10 seconds\n");
        sleep(10);             // exits first
    printf("PARENT: Sleeping is over\n");
    }

    return 0;
}

As far as I know:

  • if fork() function is called - code is executing in child and parent section (if fork() did not exits with -1 of course)
  • after calling fork() function all code after fork() is executed sequentially (but due to sheduller is unable to predict if will be executed parent or child part of code)
  • if parent code exits before child code (without waiting or hadnling signal), childs new parent will be init proces (PPID 1)

I get the following output

bash-3.2$ ./a2.out
PARENT: This is the parent process!
 CHILD: This is the child process!
PARENT: My PID is 15852
PARENT: My child's PID is 15853
PARENT: I am sleeping for 10 seconds
 CHILD: My PID is 15853
 CHILD: My parent's PID is 15852
 CHILD: I am sleeping for 15 seconds
PARENT: Sleeping is over
bash-3.2$  CHILD: Sleeping is over
PARENT: This is the parent process!
PARENT: My PID is 15853
PARENT: My child's PID is 0
PARENT: I am sleeping for 10 seconds
PARENT: Sleeping is over

So my question is:

  • why is not child mark as defunct when parent exits first ? (I tried ps -elf | grep defunct during execution of code)
  • Why is parent code executed second time (but now with the pid of child ?)

Thanks a lot

First, replace all printf(...) with fprintf(stderr, ...). There's no way to tell what's really printing what when right now, because there may be buffers getting flushed after you forked.

---------- Post updated at 07:43 PM ---------- Previous update was at 07:41 PM ----------

Also, you never put a break; at the end of the child section so it keeps running down through the parent section. imagine a case to be a goto: It just magically jumps to that location and keeps going until you tell it to stop with a break;

If you run this piece of code you will have different outcomes. Sometimes the father code can be executed before the son's code and vice-versa, because the operating systems stagger them. And a process has some limited time for accessing the CPU which is called Time Slice, when a process time slice rans out the OS switch to another process that is waiting to be executed.

All you need to know It is how the fork () syscall works and this lit.le concept.

I hope I hellped-

Thanks both - now it is clear why I had run 2 times parent (because of missing break) and also did not know that child can started before son. But anyway if I add break why I did not get the son process as defunct or zombie ?

Once the parent processes quit, the child processes change ownership to process 1, 'init', which reaps them for you. Zombies happen when the parent is still alive but not reaping its children.

Is it possible to code application this way ? - I assumed if I did not catch SIGCHLD in parent with wait() function this happens

Put a sleep(60) before the parent begins wait()ing for children and look for the children in the process table(ps). If they've quit, they should be zombies until the parent wait()'s for them.

Sort of. wait()ing for a process removes its zombie from the process table, but if the parent quits while its children are still zombies, they get owned by init, which will wait() for them itself. So zombies mostly happen while the parent is still alive.

Thank you now it is clear :slight_smile: