Linux僵尸进程与孤儿进程

发布时间 2023-09-01 17:23:02作者: xiaoyaozhe

Linux系统-部署-运维系列导航

 

模拟程序

#include <stdio.h>
#include <unistd.h>
//本程序启动一个子进程,父子进程无限循环不退出

//编译:gcc create_zombie.c -o zombie
//执行:./zombie

//使用方法
//kill父进程,则子进程变为孤儿进程,可以kill子进程解决
//kill子进程,则子进程变为僵尸进程,可以kill父进程解决
int main()
{
    //fork一个进程,作为子进程
    printf("fork a child process\n");
    pid_t pid = fork();
 
    if (pid > 0)
    {
        //父进程
        printf("---i am parent: %d\n", getpid());
    }
    else if (pid == 0) 
    {
        //子进程
        printf("---i am child: %d\n", getpid());
    }

    //死循环,避免进程退出,方便人为操作模拟孤儿进程与僵尸进程    
    while(1)
    {
        sleep(1);
    } 
    
    return 0;
}
 

僵尸进程

处于僵死状态的进程危害:会造成资源泄漏
僵尸进程的产生原因:子进程先于父进程退出,因为要保留退出原因,因此操作系统不能直接释放所有资源,通知父进程获取退出原因,允许操作系统释放资源,但是父进程没有关注这个通知导致子进程退出后无法释放所有资源,处于僵死状态成为僵尸进程
如何处理:结束掉父进程,僵尸进程也就结束了
如何识别:进程状态为 Z+,可以通过 top 命令(确认僵尸进程数量)以及 ps 命令(确认进程状态)
[root@localhost ~]# top
top - 14:20:31 up 20:31,  2 users,  load average: 0.31, 0.40, 0.46
Tasks: 111 total,   1 running, 109 sleeping,   0 stopped,   1 zombie

[root@localhost ~]# ps -A -ostat,ppid,pid,cmd | grep -e '^[Zz]'
Z+    6720  6721 [zombie] <defunct>
 

孤儿进程

处于孤儿状态的进程危害:除程序自身业务完整性外,一般来说,孤儿进程并不会有什么危害
孤儿进程的产生原因:父进程先于子进程退出,子进程就会成为孤儿进程,运行在后台,父进程成为1号进程(init初始化进程)
如何处理:结束掉子进程即可
如何识别:进程状态转为后台,即状态没有+号,父进程ID变为 1,可以通过 ps 命令(确认进程状态)
[root@localhost ~]# ps -A -ostat,ppid,pid,cmd | grep zombie
S+    6858  6928 ./zombie
S+    6928  6929 ./zombie



[root@localhost ~]# kill -9 6928
[root@localhost ~]# ps -A -ostat,ppid,pid,cmd | grep zombie
S        1  6929 ./zombie
 

附录:Linux进程状态

D   不可中断睡眠 (通常是在IO操作) 收到信号不唤醒和不可运行, 进程必须等待直到有中断发生
R   正在运行或可运行(在运行队列排队中)
S   可中断睡眠 (休眠中, 受阻, 在等待某个条件的形成或接受到信号)
T   已停止的 进程收到SIGSTOP, SIGSTP, SIGTIN, SIGTOU信号后停止运行
W   正在换页(2.6.内核之前有效)
X   死进程 (未开启)
Z   僵尸进程  进程已终止, 但进程描述符存在, 直到父进程调用wait4()系统调用后释放BSD风格的
<   高优先级(not nice to other users)
N   低优先级(nice to other users)
L   页面锁定在内存(实时和定制的IO)
s   一个信息头
l   多线程(使用 CLONE_THREAD,像NPTL的pthreads的那样)
+   在前台进程组