linux-查找并清除僵死的进程

 

僵尸进程的产生

停止进程的方法有很多,但进程停止后有些信息对父进程和内核还是有用的,

例如进程的退出状态,进程运行的CPU时间,进程的ID号等,

因此进程在终止时,会回收所有内核给予分配的内存,关闭进程打开的所有文件等,

但是还是会保留极少的信息,来供父进程使用,父进程可以使用wait/waitpid等系统调用来为子进程做点收尾工作。

 

因此,一个僵尸进程产生的过程是,父进程调用fork创建子进程后,子进程运行直终止,它立即从内存中移除,

但进程描述符仍然保留在内存中(进程描述符占用极少的内存空间),子进程的状态变成EXIT_ZOMBIE

并且向父进程发送SIGCHLD信号,父进程此时应该调用wait()系统来获取子进程的退出状态以及其它相关的信息,

wait调用过后,僵尸进程就会完全从内存中移除,因此一个僵尸进程存在到终止到父进程调用wait函数的时间之间,一般很快就会消失,

但如果编程不合理,父进程从不调用wait等系统来收集僵尸进程,那么这些进程会一直存在内存中,最后形成僵尸进程

 

 

 

检测系统中的僵尸进程

这里提供一个方法

ps -e -o stat,ppid,pid,cmd | egrep '^[Zz]'

stat:状态信息
ppid:父进程pid
pid:当前进程的pid
cmd:即进程的可执行文件

ps:用于查询系统进程
    -e:用于列出所有的进程
    -o:用于设定输出的格式

egrep:正则表达式查询工具
    '^[Zz]':正则表达式,僵尸进程的状态信息是以z或Z字母开头

可以通过查询出来的pid来进行kill杀死僵尸进程

kill其实是将僵尸进程的父进程杀掉,进而关闭僵尸进程

因为僵尸进程已经是死掉的进程,不可能在接收任何信号

所以就需要通过kill了僵尸进程的父进程,这样父进程杀掉后,僵尸进程就成为孤儿进程

而所有的孤儿进程都会交给系统的1号进程(initsystemd)收养,1号进程会周期性的去调用wait系统来清除僵尸进程,

因为将僵尸的父进程杀掉之后,僵尸进程也会跟着消失,这也是1号进程的作用

 

 

 

 

避免产生僵尸进程

kill僵尸进程,是治标不治本,最好的方法,就是不让其产生僵尸进程

 

第一个办法

在父进程创建子进程之前,就向系统申明自己并不会对这个子进程的exit动作进行任何关注行为,

这样,子进程一旦退出了,系统也不会去等待父进程的操作,而是真的将子进程的资源回收,这样就不会产生僵尸进程了

 

第二个办法

在父进程创建子进程的时候,连续调用再次fork(),而且使紧跟的子进程直接退出,使子进程变成孤儿进程,

从而让1号进程接替父进程,来清除孤儿进程,这样父进程就无需任何的清理行为,系统会自动处理

 

 

 

 

 

转载请注明原文链接:linux-查找并清除僵死的进程

发表评论:

共有 0 条评论

 Top