一、为什么存在僵尸进程
首先需要明确指出的是,僵尸进程是Linux操作系统中所特有的一种进程状态!!
为什么会存在僵尸进程呢?正常来说,我们运行一个进程,必然是希望完成某种任务。但我们如何知道任务完成的怎么呢?通常进程在退出时会返回一些信息(例如C语言中,我们执行main函数
时返回0,表示任务完美完成;如果返回3221225477,表示程序中存在越界访问)。而该进程的退出信息会被返回给该进程的父进程或者操作系统,让父进程或OS得知进程为何退出!!
其中进程返回的退出信息首先会由操作系统写入该进程的PCB中,此时操作系统运行将进程的代码和数据内存空间被释放。至于PCB,只有当父进程或操作系统读取到该进程的退出原因时,才能被释放。
像上述这种情况,进程已经退出了,但进程退出信息还未被父进程或操作系统读取到时,OS必须维护该退出进程的PCB。我们将此时进程的状态称之为僵尸状态,此时该进程被称为僵尸进程!!
二、僵尸(死)进程的概念
僵尸状态(Zombies):当子进程退出而父进程未退出时,并且父进程还未读取到子进程的返回代码时的一种特殊进程状态。(Linxu操作系统特有)
僵死进程会以终止状态保持在进程表中,并且会一直在等待父进程读取退出状态代码。所以,只要子进程退出,父进程还在运行,但父进程没有读取子进程状态,子进程进入Z状态。
三、僵尸进程状态展示
下面我们通过fork()在代码中创建子进程,然后通过Makefile/make进行编译,最后通过右边的进程监视脚本观察进程状态的变化!
【code.c源文件】:
#include <stdio.h> #include <unistd.h> int main() { pid_t id = fork(); if(id < 0) return 1;//子进程创建失败 else if(id == 0) {//子进程 int cnt = 5; while(cnt) { printf("I am child, run times:%d\n", cn t--); sleep(1); } exit(1); } else {//父进程 while(1) { printf("I am father, run anytimes\n"); sleep(1); } } return 0; }
【动画展示】:
我们在动画展示中,发现子进程在运行5次循环后退出进程,进程退出,进程状态应该变为X死亡状态
,但我们实际上观察到的确实Z僵尸状态
(+
表示改进为前台进程)。也进一步验证僵尸进程的存在!
四、僵尸进程的危害
当进程处于僵尸状态时,操作系统要一直维护该进程的PCB。而PCB是数据,在内存占据内存空间。如果一个父进程创建了很多子进程,但就是不回收,此时就会导致内存泄漏
!!