<返回更多

什么是Linux僵尸进程?怎么产生的?怎么避免?

2019-07-03    
加入收藏

僵尸进程是指它的父进程已经退出(父进程没有等待(调用wait/waitpid)它),而该进程dead之后没有进程接受,就成为僵尸进程,也就是(zombie)进程。

什么是Linux僵尸进程?怎么产生的?怎么避免?

 

 

一个进程在调用了exit命令之后结束了自己的生命时候,你以为是真的被彻底销毁了吗?其实不然,它只是变成了我们称之为“僵尸进程”状态。在用户态程序调用系统调用exit时,也仅仅限于将一个正常的进程变成了一个僵尸进程,并没有完全的销毁。看下图所示:

 

什么是Linux僵尸进程?怎么产生的?怎么避免?

 

 

linux中,进程的状态有5种,其中僵尸进程状态是一种比较奇葩的存在方式,它放弃了几乎所有的内存地址空间,也没有任何的可执行的代码,也不可能被调度器再次调度,它仅仅是在进程列表中保留一个位置,在这个位置中记载了该进程的状态。而它也只是静静的等待着其他进程(父进程后者init进程)为他收尸。

假如它的父进程没有安装SIGCHLD信号处理函数来处理子进程(也即使wait或者waitpid等待儿子结束),又没有显示忽略该信号,那子进程就会一直保持僵尸状态。只有在父进程结束之后,才由init进程接管子进程,为他收尸(好凄惨啊),这个时候才能说子进程才真正的消失在Linux内核中。

又假如父进程是个无限循环的进程,那么子进程就会一直保持僵尸状态。这就能解释为什么系统运行久了,会出现大量的僵尸状态的进程。出现僵尸状态进程的数量少,是没有任何问题的,一旦出现巨量情况,就会导致PID用完,而给新的进程分配PID,当然也就会创建新进程失败。

为什么要有僵尸状态呢?

主要是因为父进程可能要取得子进程的退出状态等信息。僵尸状态是每一个进程必须要经过的过程(除init进程之外)。

 

那怎么避免呢?

当前能给出四种方案,分别是:

  1. 父进程通过wait或waitpid函数等待子进程结束,这样有个问题,就是会导致父进程挂起。
  2. 如果父进程很忙,可以采用异步的方式,注册SIGCHLD信号处理函数,在处理函数中wait回收子进程。
  3. 如果父进程对子进程生死不感兴趣,也可以通过signal(SIGCHLD,SIG_IGN)告知内核,忽视掉该信号。当然子进程结束后,内核会帮助回收。
  4. 还可以用一些技巧,比如fork两次。子进程退出,孙进程就由init进程接管回收了。这个方法的代码网络上多如牛毛。自信百度查看。

如何查看僵尸进程呢?

在Linux中,可以使用ps命令,ps 命令就是最根本相应情况下也是相当强大地进程查看命令.运用该命令可以确定有哪些进程正在运行和运行地状态、 进程 是否结束、进程有没有僵死、哪些进程占用了过多地资源等等.总之大部分信息均为可以通过执行该命令得到地.

标记“Z”的进程就是僵尸进程了。

ps -ef

可以用ps的-l选项,得到更详细的进程信息.

F(Flag):一系列数字的和,表示进程的当前状态。这些数字的含义为:

00:若单独显示,表示此进程已被终止。
01:进程是核心进程的一部分,常驻于系统主存。如:sched、 vhand 、bdflush 等。
02:Parent is tracing process.
04:Tracing parent’s signal has stopped the process; the parent is waiting ( ptrace(S)).
10:进程在优先级低于或等于25时,进入休眠状态,而且不能用信号唤醒,例如在等待一个inode被创建时   
20:进程被装入主存(primary memory)
40:进程被锁在主存,在事务完成前不能被置换

S(state of the process )

  O:进程正在处理器运行 
  S:休眠状态(sleeping)
  R:等待运行(runable)   
  I:空闲状态(idle)
  Z:僵尸状态(zombie)   
  T:跟踪状态(Traced)
  B:进程正在等待更多的内存页
  C:cpu利用率的估算值(cpu usage)

另外使用top命令查看时有一栏为S,如果状态为Z说明它就是僵尸进程。

声明:本站部分内容来自互联网,如有版权侵犯或其他问题请与我们联系,我们将立即删除或处理。
▍相关推荐
更多资讯 >>>