什么是僵尸进程?
在UNIX/Linux系统中,通过fork创建子进程。子进程结束时,他的父进程并没有等待(调用wait/waitpid)他,则他成为一个僵尸进程。但如果该进程的父进程已经结束了,那么该进程就不会变成僵尸进程,因为每个进程结束的时候,系统都会扫描当前系统中所运行的所有进程,看有没有哪个进程是刚刚结束的这个进程的子进程,如果是的话就交由PID为1的init进程来接管他,init成为这个进程的父进程。父进程先终止就没有事~
一个进程在调用exit命令结束自己生命的时候,其实它并没有真正的被销毁,而是留下一个称为僵尸进程(Zombie)的数据结构。系统调用exit的作用是使进程退出,但也仅仅限于将一个正常的进程变成一个僵尸进程,并不能将其完全销毁。在Linux进程的状态中,僵尸进程是非常特殊的一种,它已经放弃了几乎所有的空间,没有任何可执行代码,也不能被调度,仅仅在进程的列表中保留一个位置,记载该进程的退出状态等信息供其他进程收集。除此之外,僵尸进程不再占有任何内存空间。它需要他的父进程来为他收尸,如果他的父进程没有安装SIGCHLD信息处理函数调用wait或waitpid等待子进程的结束,又没有显示忽略该信息,那么它就一直保持僵尸状态,如果这时候父进程结束了,那么init进程自动会接手这个子进程,为它收尸,它还是能被清除的。但是如果父进程是一个循环,不会结束,那么子进程交一直保持僵尸状态,这就是为什么系统中有时会有很多僵尸进程。
查看僵尸进程的命令:ps。一些系统可能使用<zmobie>而不是<defunct>标注僵尸进程。
写一个僵尸进程的例子看看:
编译这个程序:gcc –o test test.c
后台运行这个程序:./test &
使用ps命令查看进程状态:
PID TTY TIME CMD
28393 pts/1 00:00:00 bash
28908 pts/1 00:00:00 test
28909 pts/1 00:00:00 test <defunct>
28911 pts/1 00:00:00 ps
当然,这个时候父进程一直在输出Parent!
我们要把它Kill掉,输入命令:kill 28908。
世界清静了~