Zombie and orphan processes
Zombie process (from wikipedia) When a process ends, all of the memory and resources associated with it are deallocated so they can be used by other processes. When a process ends, all of the memory and resources associated with it are deallocated so they can be used by other processes.
Zombie process (from wikipedia) However, the process's entry in the process table remains. However, the process's entry in the process table remains. The parent is sent a SIGCHLD signal indicating that a child has died; the handler for this signal will typically execute the wait system call, which reads the exit status and removes the zombie. The parent is sent a SIGCHLD signal indicating that a child has died; the handler for this signal will typically execute the wait system call, which reads the exit status and removes the zombie. The zombie's process ID and entry in the process table can then be reused. The zombie's process ID and entry in the process table can then be reused. However, if a parent ignores the SIGCHLD, the zombie will be left in the process table. However, if a parent ignores the SIGCHLD, the zombie will be left in the process table.
Orphan process (from wikipedia) A zombie process is not the same as an orphan process. A zombie process is not the same as an orphan process. Orphan processes don't become zombie processes; instead, they are adopted by init (process ID 1), which waits on its children. Orphan processes don't become zombie processes; instead, they are adopted by init (process ID 1), which waits on its children.
Example child process code printf( "child: %s running with %d arg(s). \n", argv[0], argc ); puts( "child: sleeping" ); sleep( 15 ); puts( "child: bye" ); return 0;
Parent that creates an orphan. puts( "parent: forking" ); puts( "parent: forking" ); pid_t ret = fork(); //now there’s two of us! pid_t ret = fork(); //now there’s two of us! switch (ret) { //which one? switch (ret) { //which one? case -1: //here when fork failed case -1: //here when fork failed puts( "parent: error: fork failed!" ); puts( "parent: error: fork failed!" ); break; break; case 0: //here when executing in child case 0: //here when executing in child puts( "child: here (before execl)!" ); puts( "child: here (before execl)!" ); if (execl( "./childTest.exe", "./childTest.exe", 0 )==-1) if (execl( "./childTest.exe", "./childTest.exe", 0 )==-1) perror( "child: execl failed:" ); perror( "child: execl failed:" ); puts( "child: here (after execl)!" ); //should never get here puts( "child: here (after execl)!" ); //should never get here break; break; default: //here when executing in parent default: //here when executing in parent printf( "parent: child has pid=%d \n", ret ); printf( "parent: child has pid=%d \n", ret ); puts( "parent: bye" ); puts( "parent: bye" ); break; break; } return 0; return 0;
Parent that creates a zombie (but only for 2 minutes). puts( "parent: forking" ); puts( "parent: forking" ); pid_t ret = fork(); switch (ret) { case -1: //here when fork failed case -1: //here when fork failed puts( "parent: error: fork failed!" ); puts( "parent: error: fork failed!" ); break; break; case 0: //here when executing in child case 0: //here when executing in child puts( "child: here (before execl)!" ); puts( "child: here (before execl)!" ); if (execl( "./childTest.exe", "./childTest.exe", 0 )==-1) if (execl( "./childTest.exe", "./childTest.exe", 0 )==-1) perror( "child: execl failed:" ); perror( "child: execl failed:" ); puts( "child: here (after execl)!" ); //should never get here puts( "child: here (after execl)!" ); //should never get here break; break; default: //here when executing in parent default: //here when executing in parent printf( "parent: child has pid=%d \n", ret ); printf( "parent: child has pid=%d \n", ret ); puts( "parent: sleeping" ); puts( "parent: sleeping" ); sleep( 120 ); sleep( 120 ); puts( "parent: bye" ); puts( "parent: bye" ); break; break;} return 0;
What does a zombie look like? normal (no zombie) normal (no zombie) $ ps PID TTY TIME CMD 1074 pts/2 00:00:00 bash 1280 pts/2 00:00:00 parentTest.exe 1281 pts/2 00:00:00 childTest.exe 1283 pts/2 00:00:00 ps
What does a zombie look like? abnormal (zombie) abnormal (zombie) $ ps PID TTY TIME CMD 1074 pts/2 00:00:00 bash 1280 pts/2 00:00:00 parentTest.exe 1281 pts/2 00:00:00 childTest.exe 1281 pts/2 00:00:00 childTest.exe 1288 pts/2 00:00:00 ps
What does a zombie look like? $ ps -l Warning: /boot/System.map has an incorrect kernel version. F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD 000 S a418 pts/2 00:00:00 bash 000 S f22b pts/2 00:00:00 parentTes 004 Z ffb pts/2 00:00:00 childTest 000 R pts/2 00:00:00 ps
Zombie process (from wikipedia) When a process ends, all of the memory and resources associated with it are deallocated so they can be used by other processes. However, the process's entry in the process table remains. When a process ends, all of the memory and resources associated with it are deallocated so they can be used by other processes. However, the process's entry in the process table remains. The parent is sent a SIGCHLD signal indicating that a child has died; the handler for this signal will typically execute the wait system call, which reads the exit status and removes the zombie. The parent is sent a SIGCHLD signal indicating that a child has died; the handler for this signal will typically execute the wait system call, which reads the exit status and removes the zombie. The zombie's process ID and entry in the process table can then be reused. However, if a parent ignores the SIGCHLD, the zombie will be left in the process table. The zombie's process ID and entry in the process table can then be reused. However, if a parent ignores the SIGCHLD, the zombie will be left in the process table.
Avoiding zombies To avoid creating zombie processes, the parent must: To avoid creating zombie processes, the parent must: 1. Handle the SIGCHLD signal. See man signal. See man signal. 2. In this signal handling function, the parent must wait for the child process. See man 2 wait (linux) or man –s 3C wait (solaris). See man 2 wait (linux) or man –s 3C wait (solaris). We will explore signals as an interprocess communications (IPC) mechanism shortly. We will explore signals as an interprocess communications (IPC) mechanism shortly.