转自:https://www.cnblogs.com/Anker/p/3271773.html

1.僵尸进程如何产生?

僵尸进程是当子进程比父进程先结束,而父进程又没有回收子进程,释放子进程占用的资源,此时子进程将成为一个僵尸进程。如果父进程先退出 ,子进程被init接管,子进程退出后init会回收其占用的相关资源。
在UNIX 系统中,一个进程结束了,但是他的父进程没有等待(调用wait / waitpid)他, 那么他将变成一个僵尸进程。 但是如果该进程的父进程已经先结束了,那么该进程就不会变成僵尸进程, 因为每个进程结束的时候,系统都会扫描当前系统中所运行的所有进程, 看有没有哪个进程是刚刚结束的这个进程的子进程,如果是的话,就由Init 来接管他,成为他的父进程……

我们知道在unix/linux中,正常情况下,子进程是通过父进程创建的,子进程在创建新的进程。子进程的结束和父进程的运行是一个异步过程,即父进程永远无法预测子进程 到底什么时候结束。 当一个 进程完成它的工作终止之后,它的父进程需要调用wait()或者waitpid()系统调用取得子进程的终止状态。

孤儿进程:一个父进程退出,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程。孤儿进程将被init进程(进程号为1)所收养,并由init进程对它们完成状态收集工作。

僵尸进程:一个进程使用fork创建子进程,如果子进程退出,而父进程并没有调用wait或waitpid获取子进程的状态信息,那么子进程的进程描述符仍然保存在系统中。这种进程称之为僵死进程。

2.问题及危害

unix提供了一种机制可以保证只要父进程想知道子进程结束时的状态信息, 就可以得到。这种机制就是: 在每个进程退出的时候,内核释放该进程所有的资源,包括打开的文件,占用的内存等。 但是仍然为其保留一定的信息(包括进程号the process ID,退出状态the termination status of the process,运行时间the amount of CPU time taken by the process等)。直到父进程通过wait / waitpid来取时才释放。 但这样就导致了问题,如果进程不调用wait / waitpid的话, 那么保留的那段信息就不会释放,其进程号就会一直被占用,但是系统所能使用的进程号是有限的,如果大量的产生僵死进程,将因为没有可用的进程号而导致系统不能产生新的进程. 此即为僵尸进程的危害,应当避免。

孤儿进程是没有父进程的进程,孤儿进程这个重任就落到了init进程身上,init进程就好像是一个民政局,专门负责处理孤儿进程的善后工作。每当出现一个孤儿进程的时候,内核就把孤 儿进程的父进程设置为init,而init进程会循环地wait()它的已经退出的子进程。这样,当一个孤儿进程凄凉地结束了其生命周期的时候,init进程就会代表党和政府出面处理它的一切善后工作。因此孤儿进程并不会有什么危害。

任何一个子进程(init除外)在exit()之后,并非马上就消失掉,而是留下一个称为僵尸进程(Zombie)的数据结构,等待父进程处理。这是每个 子进程在结束时都要经过的阶段。如果子进程在exit()之后,父进程没有来得及处理,这时用ps命令就能看到子进程的状态是“Z”。如果父进程能及时 处理,可能用ps命令就来不及看到子进程的僵尸状态,但这并不等于子进程不经过僵尸状态。 如果父进程在子进程结束之前退出,则子进程将由init接管。init将会以父进程的身份对僵尸状态的子进程进行处理。

僵尸进程危害场景:

例如有个进程,它定期的产 生一个子进程,这个子进程需要做的事情很少,做完它该做的事情之后就退出了,因此这个子进程的生命周期很短,但是,父进程只管生成新的子进程,至于子进程 退出之后的事情,则一概不闻不问,这样,系统运行上一段时间之后,系统中就会存在很多的僵死进程,倘若用ps命令查看的话,就会看到很多状态为Z的进程。 严格地来说,僵死进程并不是问题的根源,罪魁祸首是产生出大量僵死进程的那个父进程。因此,当我们寻求如何消灭系统中大量的僵死进程时,答案就是把产生大 量僵死进程的那个元凶枪毙掉(也就是通过kill发送SIGTERM或者SIGKILL信号啦)。枪毙了元凶进程之后,它产生的僵死进程就变成了孤儿进 程,这些孤儿进程会被init进程接管,init进程会wait()这些孤儿进程,释放它们占用的系统进程表中的资源,这样,这些已经僵死的孤儿进程 就能瞑目而去了。

3.僵尸进程解决办法

1)通过信号机制
  子进程退出时向父进程发送SIGCHILD信号,父进程处理SIGCHILD信号。在信号处理函数中调用wait进行处理僵尸进程。测试程序如下所示:

#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
#include <signal.h>static void sig_child(int signo);int main()
{pid_t pid;//创建捕捉子进程退出信号signal(SIGCHLD,sig_child);pid = fork();if (pid < 0){perror("fork error:");exit(1);}else if (pid == 0){printf("I am child process,pid id %d.I am exiting.\n",getpid());exit(0);}printf("I am father process.I will sleep two seconds\n");//等待子进程先退出sleep(2);//输出进程信息system("ps -o pid,ppid,state,tty,command");printf("father process is exiting.\n");return 0;
}static void sig_child(int signo)
{pid_t        pid;int        stat;//处理僵尸进程while ((pid = waitpid(-1, &stat, WNOHANG)) >0)printf("child %d terminated.\n", pid);
}

测试结果如下所示:

2)fork两次
  《Unix 环境高级编程》8.6节说的非常详细。原理是将子进程成为孤儿进程,从而其的父进程变为init进程,通过init进程可以处理僵尸进程。测试程序如下所示:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>int main()
{pid_t  pid;//创建第一个子进程pid = fork();if (pid < 0){perror("fork error:");exit(1);}//第一个子进程else if (pid == 0){//子进程再创建子进程printf("I am the first child process.pid:%d\tppid:%d\n",getpid(),getppid());pid = fork();if (pid < 0){perror("fork error:");exit(1);}//第一个子进程退出else if (pid >0){printf("first procee is exited.\n");exit(0);}//第二个子进程//睡眠3s保证第一个子进程退出,这样第二个子进程的父亲就是init进程里sleep(3);printf("I am the second child process.pid: %d\tppid:%d\n",getpid(),getppid());exit(0);}//父进程处理第一个子进程退出if (waitpid(pid, NULL, 0) != pid){perror("waitepid error:");exit(1);}exit(0);return 0;
}

测试结果如下所示:

僵尸进程(Zombie process )相关推荐

  1. linux僵尸程序,什么是僵尸进程(zombie)?

    僵尸进程是指一个已经终止.但是其父进程尚未对其进行善后处理获取终止进程的有关信息的进程,这个进程被称为"僵尸进程"(zombie). 怎样产生僵尸进程 一个进程在调用exit命令结 ...

  2. 僵尸进程zombie与孤儿进程orphan

    代码已上传至https://github.com/gatieme/AderXCoding/tree/master/system/unix/zombie 问题提出 以前在学习<unix环境高级编程 ...

  3. 查询php僵死进程,linux查找僵尸进程(zombie进程)

    首先,我们可以用top命令来查看服务器当前是否有僵尸进程,可以看到第二行行尾有个 0 zombie,如果数字大于0,那么意味着服务器当前存在有僵尸进程 可以用ps和grep命令寻找僵尸进程 ps -A ...

  4. linux defunct 进程,Linux僵尸进程(Zombie or defunct)

    僵尸进程(Zombie or defunct)关于Linux僵尸进程,一般是由于子进程结束的时候,会有一些资源没有释放掉,直到父进程结束或者由父进程去处理它才可以! www.cit.cn 僵尸进程就是 ...

  5. 如何察看僵尸进程 zombie

    其实这是系统维护每天必看的东西,都非常简单,也就是把平常使用的 ps -ef 多加一个l就可以看到更多详细的信息. top - 23:59:03 up 45 min,  6 users,  load ...

  6. 僵尸进程(zombie)以及避免方法

    僵尸进程在多进程环境下,父进程要长时间运行 ,期间可能创建子进程,然后子进程有 退出时,但是父进程还在运行,这时就产生了zombie进程.     子进程退出后,在进程表中还要占一项,并且子进程的一些 ...

  7. linux下的僵尸进程 - Zombie

    在linux中你可能进程听到有僵尸进程,那么究竟什么是僵尸进程,他又是怎样产生的呢?下面我们通过1个例子来说明一下. 我们知道退出一个进程用系统调用exit, 但是这并不意味着该进程马上就消失了,事实 ...

  8. Linux:僵尸进程 Zombie;waitpid

    文章目录 参考 僵尸进程的表象 出现僵尸进程的情况 一种产生Coredump,而磁盘空间不够用 一种父进程未有waitpid回收子进程 僵尸进程的影响 system 函数调用执行的子进程 waitpi ...

  9. c 僵尸进程_演示僵尸进程的C程序

    c 僵尸进程 僵尸进程 (Zombie process) A process which has finished its execution but still has an entry in th ...

  10. Linux 僵尸进程

    Linux 允许进程查询内核以获得其父进程的 PID,或者其任何子进程的执行状态.例如,进程可以创建一个子进程来执行特定的任务,然后调用诸如 wait() 这样的一些库函数检查子进程是否终止.如果子进 ...

最新文章

  1. 3.2.1 OS之虚拟内存的基本概念(局部性原理、高速缓存、虚拟内存的实现)
  2. 鸿蒙10 5G手机,继鸿蒙后麒麟V10问世 5G时代国产操作系统将起飞
  3. rabbitmq中的消息有id吗_RabbitMQ 如何实现对同一个应用的多个节点进行广播
  4. Python——模拟轮盘抽奖游戏
  5. poj Matrix 回溯,递归,虽然对于很多人是水题,但我感觉这道题听好的嘛!!!!!!!!!!!
  6. Can't use function return value in write context 使用empty遇到报错
  7. python实现多进程监听声音播放并绘图
  8. sql基础语法(增、删、改、查)
  9. 51job导出的简历是php,前程无忧简历导出
  10. 泊松分布的特征与应用(概统2.应用)
  11. 对比找出两张Excel表的不同数据
  12. 肖文吉mysql_疯狂软件教育中心肖文吉老师_MYSQL视频教程
  13. 解决jy61陀螺仪传感器读数跳动的问题
  14. 如何解决上传到github上的图片显示不出来的问题
  15. 冶金物理化学复习【6】吉布斯自由能的变化
  16. 【Vue报错】This is probably not a problem with npm. There is likely additional logging output above
  17. 和刘备相关的人(九 )
  18. TensorFlow通过Cholesky矩阵分解实现线性回归
  19. javaweb之Html/Hss/JavaScript/BootStrap小结
  20. (贪心)CF1428E. Carrots for Rabbits

热门文章

  1. 良心安利体育运动ppt幻灯片素材网站
  2. 超好用的在线编程IDE——CS50
  3. 支付宝第三方支付保证数据的安全性
  4. 利用word分词来计算文本相似度
  5. SDU信息门户(8)组队和文件系统分析
  6. 常用颜色对应RGB颜色图
  7. win10系统小米妙享中心,在手机可搜索到电脑,与之跨屏协作
  8. 从普通温度表到高精度测量
  9. 已更新或删除的行值要么不能使该行成为唯一行
  10. 微信“跳一跳”外挂制作历程