转载自http://hi.baidu.com/xuym04/blog
1.什么是僵尸进程?
In UNIX System terminology, a process that has terminated,but whose
parent has not yet waited for it, is called a zombie.
在UNIX 系统中,一个进程结束了,但是他的父进程没有等待(调用wait / waitpid)他,
那么他将变成一个僵尸进程.
但是如果该进程的父进程已经先结束了,那么该进程就不会变成僵尸进程,
因为每个进程结束的时候,系统都会扫描当前系统中所运行的所有进程,
看有没有哪个进程是刚刚结束的这个进程的子进程,如果是的话,就由Init
来接管他,成为他的父进程,从而保证每个进程都会有一个父进程.
而Init进程会自动wait 其子进程,因此被Init接管的所有进程都不会变成僵尸进程.
一个进程在调用exit命令结束自己的生命的时候,其实它并没有真正的被销毁,
而是留下一个称为僵尸进程(Zombie)的数据结构(系统调用exit,它的作用是
使进程退出,但也仅仅限于将一个正常的进程变成一个僵尸进程,并不能将其完全销毁)
2. 僵尸进程的危害
由于子进程的结束和父进程的运行是一个异步过程,即父进程永远无法预测子进程
到底什么时候结束. 那么不会因为父进程太忙来不及waid子进程,或者说不知道
子进程什么时候结束,而丢失子进程结束时的状态信息呢?
不会.因为UNIX提供了一种机制可以保证 只要父进程想知道子进程结束时的状态信息,
就可以得到. 这种机制就是:
在每个进程退出的时候,内核释放该进程所有的资源,包括打开的文件,占用的内存等.
但是仍然为其保留一定的信息(包括进程号the process ID,退出状态the termination
status of the process,运行时间the amount of CPU time taken by the process等),
直到父进程通过wait / waitpid来取时才释放.
但这样就导致了问题,如果你进程不调用wait / waitpid的话, 那么保留的那段信息就不会
释放,其进程号就会一定被占用,但是系统所能使用的进程号是有限的,如果大量的产生
僵死进程,将因为没有可用的进程号而导致系统不能产生新的进程.
此即为僵尸进程的危害,应当避免.
3.僵尸进程的避免
1、父进程通过wait和waitpid等函数等待子进程结束,这会导致父进程挂起
2. 如果父进程很忙,那么可以用signal函数为SIGCHLD安装handler,因为子进程结束后,
父进程会收到该信号,可以在handler中调用wait回收
3. 如果父进程不关心子进程什么时候结束,那么可以用signal(SIGCHLD, SIG_IGN)
通知内核,自己对子进程的结束不感兴趣,那么子进程结束后,内核会回收,
并不再给父进程发送信号
4. 还有一些技巧,就是fork两次,父进程fork一个子进程,然后继续工作,子进程fork一
个孙进程后退出,那么孙进程被init接管,孙进程结束后,init会回收。不过子进程的回收
还要自己做。 下面就是Stevens给的采用两次folk避免僵尸进程的示例.
Example
Recall our discussion in Section 8.5 about zombie processes. If we want to write a process so that it forks a child but we don't want to wait for the child to complete and we don't want the child to become a zombie until we terminate, the trick is to call fork twice. The program in Figure 8.8 does this.
We call sleep in the second child to ensure that the first child terminates before printing the parent process ID. After a fork, either the parent or the child can continue executing; we never know which will resume execution first. If we didn't put the second child to sleep, and if it resumed execution after the fork before its parent, the parent process ID that it printed would be that of its parent, not process ID 1.
Executing the program in Figure 8.8 gives us
$ ./a.out $ second child, parent pid = 1
Note that the shell prints its prompt when the original process terminates, which is before the second child prints its parent process ID.
Figure 8.8. Avoid zombie processes by calling fork twice
#include "apue.h"
#include <sys/wait.h>
int
main(void)
...{
pid_t pid;
if ((pid = fork()) < 0) ...{
err_sys("fork error");
} else if (pid == 0) ...{ /**//* first child */
if ((pid = fork()) < 0)
err_sys("fork error");
else if (pid > 0)
exit(0); /**//* parent from second fork == first child */
/**//*
* We're the second child; our parent becomes init as soon
* as our real parent calls exit() in the statement above.
* Here's where we'd continue executing, knowing that when
* we're done, init will reap our status.
*/
sleep(2);
printf("second child, parent pid = %d ", getppid());
exit(0);
}
if (waitpid(pid, NULL, 0) != pid) /**//* wait for first child */
err_sys("waitpid error");
/**//*
* We're the parent (the original process); we continue executing,
* knowing that we're not the parent of the second child.
*/
exit(0);
}
3、僵尸进程的处理:
**它需要它的父进程来为它收尸,如果他的父进程没安装SIGCHLD信号处理函数调用wait或waitpid()等待子进程结束,又没有显式忽略该信号,那么它就一直保持僵尸状态;
存在的问题:如果父进程是一个循环,不会结束,那么子进程就会一直保持僵尸状态,这就是为什么系统中有时会有很多的僵尸进程,系统的性能可能会收到影响。
** 如果这时父进程结束了,那么init进程自动会接手这个子进程,为它收尸,它还是能被清除的。
4、子进程结束后为什么要进入僵尸状态?
* 因为父进程可能要取得子进程的退出状态等信息。
5、僵尸状态是每个子进程比经过的状态吗?
是的。
* 任何一个子进程(init除外)在exit()之后,并非马上就消失掉,而是留下一个称为僵尸进程(Zombie)的数据结构,等待父进程处理。这是每个 子进程在结束时都要经过的阶段。如果子进程在exit()之后,父进程没有来得及处理,这时用ps命令就能看到子进程的状态是“Z”。如果父进程能及时 处理,可能用ps命令就来不及看到子进程的僵尸状态,但这并不等于子进程不经过僵尸状态。
* 如果父进程在子进程结束之前退出,则子进程将由init接管。init将会以父进程的身份对僵尸状态的子进程进行处理。
6、如何查看僵尸进程:
$ ps -el
其中,有标记为Z的进程就是僵尸进程
S代表休眠状态;D代表不可中断的休眠状态;R代表运行状态;Z代表僵死状态;T代表停止或跟踪状态
分享到:
相关推荐
Linux杀死僵尸进程.zip 需要掌握的运维命令有ls、ps、free、top、uptime、ifconfig、susudo、dmesg、iostat、vmstat、sar、htop、iotop、smem等
Linux安全攻略——僵尸进程.pdf中讨论了Linux操作系统中的进程管理机制,包括进程的概念、进程调度、进程树、进程标识符、进程生命周期等方面的知识点。 进程概念 在Linux操作系统中,进程是动态的,程序是静态的...
查看僵尸进程
僵尸进程是计算机操作系统中的一种特殊状态,当一个进程执行完毕并退出,但其父进程尚未读取其退出状态时,这个已结束的进程就会成为僵尸进程。它的主要特征是进程已不再执行任何代码,但其进程描述符仍然存在于内存...
### 在Linux系统中查看进程及杀死僵尸进程的方法 #### 一、引言 在Linux操作系统中,进程管理是一项重要的任务,它涉及到系统性能优化、故障排查等多个方面。本文将详细介绍如何使用`ps`命令来查看系统中的进程...
### Linux中的僵尸进程详解 #### 一、僵尸进程的概念与形成原因 在Linux系统中,程序的执行是以进程的形式存在的。每一个进程都有一个父进程(除非是init进程,它的PID为1,没有父进程),而它自身又可以作为其他...
在操作系统(OS)中,僵尸进程是一个已终止但其父进程尚未从子进程接收状态信息的进程。这种状态是进程生命周期中的一个不寻常阶段,它可能会占用系统资源并导致不必要的混乱。本文将深入探讨消除僵尸进程的两种常用...
僵尸进程是一种特定状态的进程,当一个进程执行完毕并退出,但其父进程尚未读取它的退出状态时,该进程就会成为僵尸进程。这种状态的进程已经没有在执行任何代码,但它在系统中的进程描述符仍然存在,占用了一定的...
Linux 允许进程查询内核以获得其父进程的 PID,或者其任何子进程的执行状态。例如,进程可以创建一个子进程来执行特定的任务,然后调用诸如 wait() 这样的一些库函数检查子进程是否终止。如果子进程已经终止,那么,...
在Linux系统中,僵尸进程(Zombie Process)是一种常见的系统问题,它们通常是由父进程创建的子进程在完成任务后未能被父进程正确回收而遗留下来的。这些僵尸进程虽然不再执行任何操作,但仍然占据着系统资源,如...
dumb-init 跨框架init初始化进程,有效回收僵尸进程
僵尸进程的产生和如何避免僵尸进程的产生和如何避免僵尸进程的产生和如何避免僵尸进程的产生和如何避免
5. **事件处理**:捕获用户的键盘和鼠标输入,控制游戏的进程,如种植植物、选择技能等。 6. **得分系统**:跟踪玩家的得分,并根据游戏进度更新。 7. **存档和读取**:允许玩家保存游戏进度,方便下次继续。 8. ...
僵尸进程是Linux系统中常见的一个问题,虽然它们对系统的影响有限,但长期存在的僵尸进程会逐渐消耗系统资源。对于那些难以杀死的僵尸进程,我们需要深入分析其背后的原因,并采取相应措施来解决问题。通过上述方法...
Linux避免僵尸进程
* 已有的僵尸:普通僵尸,旗帜僵尸,路障僵尸,铁桶僵尸,读报僵尸,橄榄球僵尸,鸭子救生圈僵尸,铁门僵尸,撑杆跳僵尸,冰车僵尸,潜水僵尸 * 使用JSON文件记录关卡信息数据 * 在0.8.18.0及以后直接用python记录...
### 谈谈守护进程和僵尸进程 #### 守护进程与僵尸进程的概念及应用场景 在深入探讨守护进程和僵尸进程之前,我们先简要回顾一下这两种进程的基本概念及其应用场景。 - **守护进程**(Daemon Process):是在后台...
僵尸源码可能涉及到网络通信、模拟行为、后台任务处理等,因为“僵尸”这个词在计算机领域常用于形容在网络中悄无声息活动的进程或程序。 三、源码使用说明.txt 这个文件很可能是对源代码的详细说明,包括如何编译...
本文主要给大家介绍了关于Linux中僵尸进程和孤儿进程的相关内容,分享给出来供大家参考学习,下面来看看详细的介绍: 1、僵尸进程 一个子进程在其父进程没有调用wait()或waitpid()的情况下退出,这个子进程就是僵尸...