Linux僵尸进程的处理方式

1 查看僵尸进程

在Linux操作系统中,输入top指令就可以查看:

注意看整个界面的第二行,最后一个zombie的前面的数字就是代表僵尸进程的数量,这里看到僵尸进程数量不为0,那么就需要来清除一下僵尸进程。

2 处理僵尸进程

1)kill -9 杀死僵尸进程的父进程

接下来需要确定僵尸进程的相关信息,比如父进程ppid、僵尸进程的pid以及命令行等信息。可以执行如下命令

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

说明:

ps:ps命令用于获取当前系统的进程信息

-e:参数用于列出所有的进程

-o:参数用于设定输出格式,这里只输出进程的stat(状态信息)、ppid(父进程pid)、pid(当前进程的pid),cmd(即进程的可执行文件

egrep:是linux下的正则表达式工具:‘1’:这是正则表达式,表示第一个字符的位置,[Zz],表示z或者大写的Z字母,即表示第一个字符为Z或者z开头的进程数据,只所以这样是因为僵尸进程的状态信息以Z或者z字母开头。

然后可以kill -9 父进程pid,假设父进程pid为 1024

kill -9 1024

现在大多数linux系统,也会将僵尸进程标识为defunct,所以你也可以通过如下命令来获取僵尸进程信息。

ps -ef | grep "defunct"

一般来说先用kill命令发送强制终止的信息,结束子进程。这时候僵尸进程是没有办法结束的(不能杀死已经处于死亡状态的进程)。所以,这时候需要用kill -9来强制终止父进程。杀死父进程之后可以再次用top命令来看僵尸进程是否被清理。

2)挂起僵尸进程

上面的方法是通过结束父进程从而结束僵尸进程,这只能算是一个比较理想的情况 ,很多时候遇到僵尸进程不能结束父进程,比如父进程是1号进程init进程,那一旦结束父进程,整个系统就挂掉了,这时候则可以考虑挂起子进程,这相当于“曲线救国”。一个进程一旦挂起就相当于“什么都不做了”。可以通过执行如下命令来挂起进程。

kill -HUP 进程pid

3)父进程中调用wait/waitpid函数

当子进程终止时,内核就会向它的父进程发送一个SIGCHLD信号,父进程可以选择忽略该信号,也可以提供一个接收到信号以后的处理函数。对于这种信号的系统默认动作是忽略它。

如果不希望有过多的僵尸进程产生,则需要在父进程接收到SIGCHLD信号后就应该调用 wait 或 waitpid 函数对子进程进行善后处理,释放子进程占用的资源。

而当子进程在父进程之前终止时,内核为每个终止子进程保存了一定量的信息,所以当终止进程的父进程调用wait或waitpid时,可以得到这些信息。这些信息至少包括进程ID、该进程的终止状态、以及该进程使用的CPU时间总量。其他的进程所使用的存储区,打开的文件都会被内核释放。函数原型为:

pid_t waitpid(pid_t pid, int *statloc, int options);

若成功则返回进程ID,如果设置为非阻塞方式,返回0表示子进程状态未改变,出错时返回-1。

options参数可以设置为WNOHANG常量,表示waitpid不阻塞,如果由pid指定的子进程不是立即可用的,则立即返回0。

posted @ 2021-09-14 21:20  Jcpeng_std  阅读(2921)  评论(0编辑  收藏  举报