Sage, Simon and Simple and the unix process lifecycle

The Process Lifecycle

by: burt rosenberg
at: university of miami
date: September 12, 2010
In 1632, Galileo puts Salviati, Sagredo, and Simplicio into a four-day conversation in Dialogo sopra i due massimi sistemi del mondo. This characters: Sage, Simon and Simple, were AI generated for similar dialogs concerning operating systems principles.

This is a small experiment to show the life cycle of a unix process.

The unix book by Maurice Bach, and reproduced on this page, gives a highly detailed state transition diagram for a unix process. The conceptual outline is simpler.

A Unix process is created in the idle state, and is then moved between ready to run, running, and possibly waiting (or sleeping), until it exits and becomes a zombie.

Once a process, usually the parent process, reaps the exit status of the zombie, then the process is destroyed.

Because the number of logical threads exceeds the number of physical threads, the logical threads share time slices on the physical threads, interleaving with enough frequency so that the logical threads appear to run simultaneously. When the thread is running on a physical thread it is in the run state, and when it is not on a physical thread, and making no computational progress, it is in the ready state.

A logical thread might be in a state where it has nothing to do until some event occurs. For instance, in I/O wait. The thread is processing input and the input is being retrieved. The ask for the I/O is made in the running state, then the thread goes to the wait state, with some software magic that connects the wait to the I/O task. The completion of the task, e.g. the delivery of data, returns the thread to the ready state.

Testing and visualizing Unix fork and waits

  1. The test program uses fork to create several children processes. Each receives an integer tag.
  2. The children report their initiation, then sleep for a bit before exiting.
  3. The parent process then gathers the exit status of all the children, by repeated calls to wait, reports the exit of each child, and then itself exits.

Using the ps command, we will see the children all in the wait states, then in their zombie states, then only the parent in the wait, with the children processes gone, and finally back to the shell. The parent relationship of the process includes how bash is the parent of make, and make is the parent of the test program.

It also shows that I logged in as a normal user, UID 1000, but ran these programs as root, so there is an su and a second bash in the chain of processes.


From: Maurice Bach

The ps command options I use are,

ps jfwt 1 where,

The output includes:

The test program

debian-32:~/nicetracing# more processtest.c
/*
 * author: burt rosenberg
 * created: 12 sept 2010
 * last update: 12 sept 2010
 */

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

#define LONG_SLEEP 20
#define SHORT_SLEEP 10
#define N_CHILD 4

int main(int argc, char * argv  []) {
   int i = 0 ;
   pid_t pid ;
   int exit_status ;

   printf("Parent: starts\n") ;
   for (i=1;i<N_CHILD;i++ ) { 
      if ( !(pid = fork()) ) {
         /* child */
         printf("Child: starting %d\n", i ) ;
         fflush(NULL) ;
         sleep(SHORT_SLEEP) ;
         printf("Child: ending %d\n", i ) ;
         fflush(NULL) ;
         exit(i) ;
      }
      printf("Parent: forked child %d with pid %d\n", i, pid ) ;
      fflush(NULL) ;
   }
   sleep(LONG_SLEEP) ;
   printf("Parent: reaps ...\n") ;  
   for (i=1;i<N_CHILD;i++) {
      pid = wait(&exit_status) ;
      printf("Parent: child %d has exit code %d\n", 
         pid, WEXITSTATUS(exit_status)) ;
   }
   sleep(SHORT_SLEEP) ;
   printf("Parent: exits\n") ;  
   exit(0) ;
}

A run of the test program

debian-32:~/nicetracing#  make
cc -g -o processtest processtest.c
debian-32:~/nicetracing# make run
./processtest
Parent: starts
Child: starting 1
Parent: forked child 1 with pid 2694
Child: starting 2
Parent: forked child 2 with pid 2695
Child: starting 3
Parent: forked child 3 with pid 2696
Child: ending 1
Child: ending 2
Child: ending 3
Parent: reaps ...
Parent: child 2694 has exit code 1
Parent: child 2695 has exit code 2
Parent: child 2696 has exit code 3
Parent: exits
debian-32:~/nicetracing# 

Process tree during run


debian-32:~/nicetracing# ps jfwt 1
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
 2467  2468  2468  2468 pts/1     2482 Ss    1000   0:00 -bash
 2468  2481  2481  2468 pts/1     2482 S        0   0:00  \_ su
 2481  2482  2482  2468 pts/1     2482 S+       0   0:00      \_ bash
debian-32:~/nicetracing# ps jfwt 1
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
 2467  2468  2468  2468 pts/1     2692 Ss    1000   0:00 -bash
 2468  2481  2481  2468 pts/1     2692 S        0   0:00  \_ su
 2481  2482  2482  2468 pts/1     2692 S        0   0:00      \_ bash
 2482  2692  2692  2468 pts/1     2692 S+       0   0:00          \_ make run
 2692  2693  2692  2468 pts/1     2692 S+       0   0:00              \_ ./processtest
 2693  2694  2692  2468 pts/1     2692 S+       0   0:00                  \_ ./processtest
 2693  2695  2692  2468 pts/1     2692 S+       0   0:00                  \_ ./processtest
 2693  2696  2692  2468 pts/1     2692 S+       0   0:00                  \_ ./processtest
debian-32:~/nicetracing# ps jfwt 1
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
 2467  2468  2468  2468 pts/1     2692 Ss    1000   0:00 -bash
 2468  2481  2481  2468 pts/1     2692 S        0   0:00  \_ su
 2481  2482  2482  2468 pts/1     2692 S        0   0:00      \_ bash
 2482  2692  2692  2468 pts/1     2692 S+       0   0:00          \_ make run
 2692  2693  2692  2468 pts/1     2692 S+       0   0:00              \_ ./processtest
 2693  2694  2692  2468 pts/1     2692 Z+       0   0:00                  \_ [processtest] <defunct>
 2693  2695  2692  2468 pts/1     2692 Z+       0   0:00                  \_ [processtest] <defunct>
 2693  2696  2692  2468 pts/1     2692 Z+       0   0:00                  \_ [processtest] <defunct>
debian-32:~/nicetracing# ps jfwt 1
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
 2467  2468  2468  2468 pts/1     2692 Ss    1000   0:00 -bash
 2468  2481  2481  2468 pts/1     2692 S        0   0:00  \_ su
 2481  2482  2482  2468 pts/1     2692 S        0   0:00      \_ bash
 2482  2692  2692  2468 pts/1     2692 S+       0   0:00          \_ make run
 2692  2693  2692  2468 pts/1     2692 S+       0   0:00              \_ ./processtest
debian-32:~/nicetracing# ps jfwt 1
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
 2467  2468  2468  2468 pts/1     2482 Ss    1000   0:00 -bash
 2468  2481  2481  2468 pts/1     2482 S        0   0:00  \_ su
 2481  2482  2482  2468 pts/1     2482 S+       0   0:00      \_ bash

Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.

author: burton rosenberg
created: 12 sep 2010 (content)
update: 28 aug 2026