僵尸进程产生原因:
如果子进程先于父进程退出, 同时父进程又没有调用wait()/waitpid(),则该子进程将成为僵尸进程。
任何进程在刚终止时都是僵尸进程,正常情况下,僵尸进程都立刻被父进程清理了。
通过ps命令,我们可以看到该进程的状态为Z(表示僵死),有些unix系统在ps命令输出的COMMAND栏以<defunct>指明僵尸进程。
如何产生:
在UNIX 系统中,一个进程结束了,但是他的父进程没有等待(调用wait / waitpid)他,那么他将变成一个僵尸进程。通过ps命令查看其带有defunct或者z的标志。僵尸进程是一个早已死亡的进程,但在进程表中仍占了一个位置。
但是如果该进程的父进程已经先结束了,那么该进程就不会变成僵尸进程。因为每个进程结束的时候,系统都会扫描当前系统中所运行的所有进程,看看有没有哪个 进程是刚刚结束的这个进程的子进程,如果是的话,就由Init进程来接管他,成为他的父进程,从而保证每个进程都会有一个父进程。而Init进程会自动 wait其子进程,因此被Init接管的所有进程都不会变成僵尸进程。
僵尸进程的危害:
在进程退出的时候,内核释放该进程所有的资源,包括打开的文件,占用的内存等。但是仍然为其保留一定的信息(包括进程号 PID,退出状态,运行时间等)。直到父进程通过 wait / waitpid 来取时才释放。如果进程不调用 wait / waitpid 的话,那么保留的那段信息就不会释放,其进程号就会一直被占用,但是系统所能使用的进程号是有限的,如果大量的产生僵死进程,将因为没有可用的进程号而导致系统不能产生新的进程。
如何解决:
当系统中出现了僵尸进程时,我们是无法通过 kill 命令把它清除掉的。但是我们可以杀死它的父进程,让它变成孤儿进程,并进一步被系统中管理孤儿进程的进程收养并清理。命令:ps -ef | grep defunct_process_pid 可以找到僵尸进程的父进程。