Linux僵尸进程

1. 僵尸进程认识

1.1 什么是僵尸进程

子进程结束,父进程没有正确处理子进程返回信息。
PS:直到父进程退出,子进程变为孤儿进程,其父进程会变为Init进程(PPID=0),Init进程会负责清理僵尸进程。

1.2 危害

僵尸进程没有从进程列表删除,占据内核资源。

1.3 结论

多进程编程,父进程需要跟踪子进程的退出状态。

1.4 僵尸进程查看方法
  1. top (zombie数量)
  2. ps -ef |grep defunct
1.5 僵尸进程处理方法

当子进程结束,其会给父进程发送SIGCHLD信号。
这时父进程捕获信号后可调用wait()或者waitpid()函数回收子进程尸体 1. pid_t wait (int * status); 2. pid_t waitpid(pid_t pid,int * status,int options);

PS:使用waitpid就够了,其为wait提供非阻塞功能,也可简单使用signal(SIGCHLD,SIG_IGN);这时内核在子进程结束不会产生僵尸进程

1.6 编程例子
#include <iostream>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
using namespace std;

void OnSigChild(int iSig)
{
    pid_t iPid;
    int iStat;
    while ((iPid = waitpid(-1, &iStat, WNOHANG)) > 0)
    {
        cout << "<OnSigChild>, Pid=" << iPid << endl;
    }
}

int main()
{
    signal(SIGCHLD, OnSigChild);
    if (!fork())
    {
        // Child
        cout << "Child:" << getpid() << endl;
        exit(0);
    }

    // Parent
    while(1);
    return 0;
}

注意: 子进程未结束,而父进程先结束了,子进程PPID变为0(Init进程)。这时ps -ef子进程并不是僵尸态,而是孤儿进程

2. 僵尸进程处理

2.1 如何杀死僵尸进程

一般僵尸进程很难直接kill掉,不过您可以kill僵尸的父进程。父进程死后,僵尸进程成为孤儿进程,过继给1号进程init,init始终会负责清理僵尸进程.它产生的所有僵尸进程也跟着消失。执行如下命令:

ps -e -o ppid,stat | grep Z | cut -d “ ” -f2 | xargs kill -9
Editing is enabled. Use the "Save changes" button below the editor to commit modifications to this file.