First off, a zombie process isn’t really a process. At least it’s not executing anymore. A zombie process is more of a “state”, and that state is “defunct”. However, we typically refer to them as “zombie processes”, so I’ll stick with convention here. Second, a zombie process on a Unix system is a child process that has not been waited on by the parent. In a typical scenario, when a child process is finished executing its task, the chain of events will go something like this:
- Child process issues the signal SIGCHLD to the parent.
- Parent receives SIGCHLD, issues the “wait()” system call.
- Parent now receives the exit code of the child.
- Parent reaps the child from the process table.
So, when the child process has finished execution of its task, it will report the exit code to the parent. At this point, the child process will remain in the process table until it receives further instruction from the parent. This wait is the defunct, or zombie state. So, in reality, child processes are in this state all the time. It’s just that normally, the parent process acts on it immediately. When the parent does not respond, then we have the zombie state of that child process.
You can check if there are any zombie processes on your system with the following command:
$ ps -eo pid,ppid,user,args,stat --sort stat
Any state of “Z” is a zombie state. So, the question becomes, how do you clean out the zombie, if it is causing issues with your system? Well, you have 3 options:
- Physically wait around. Sometimes, the parent is busy, and just hasn’t acknowledged the child. When the parent is free, it could clean it up.
- Send the “SIGCHLD” signal to the parent process. The above command will give you that output in the “PPID” column.
- Fully kill the parent process. Any child processes will be orphaned, and picked up by INIT. INIT does frequent reaping of child processes and will reap any zombie states.