This is a small experiment to show the life cycle of a unix process. 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.
The test program uses fork to create several children processes. Each receives an integer tag. The children then sleep for a bit then exit. The parent process sleeps after creating the children, waiting a short time after the children all exit before proceeding. The parent will then gather the output status of all the children, by repeated calls to wait, then wait again, then exit.
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.
Table of contents
The ps command lists and gives information on the currently running processes. Definitely consult the man pages to figure out which version of ps is installed on your system. The Debian ps allows for BSD style options, if the option letters have no dash, or Posix style options, if the options letters are preceeded by a dash. I am using:
where,The output includes:
debian-32:~/nicetracing# more Makefile CC= cc CFLAGS= -g FILE= processtest all: ${CC} ${CFLAGS} -o ${FILE} ${FILE}.c run: ./${FILE}
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) ; }
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#
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