linux僵尸进程 僵尸进程如何kill
大家好,今天给各位分享linux僵尸进程的一些知识,其中也会对僵尸进程如何kill进行解释,文章篇幅可能偏长,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在就马上开始吧!
Linux中的孤儿进程与僵尸进程
Linux中的孤儿进程与僵尸进程
孤儿进程定义为:当一个父进程退出,而它的一个或多个子进程还在运行时,这些子进程将成为孤儿进程。孤儿进程将被init进程(进程号为1)收养,由init进程负责它们的状态收集工作。
僵尸进程定义为:在进程使用fork创建子进程后,如果子进程退出,而父进程没有调用wait或waitpid来获取子进程的状态信息,那么子进程的进程描述符仍然保存在系统中,这种进程称之为僵死进程。
僵尸进程的危害在于,如果进程不调用wait/ waitpid,那么保留的信息就不会释放,进程号就会一直占用,导致系统可用的进程号不足,从而影响系统产生新进程的能力。
孤儿进程的危害在于,没有父进程,孤儿进程的重任落在了init进程上。init进程负责处理孤儿进程的善后工作,因此孤儿进程不会对系统造成危害。
僵尸进程的危害场景包括:定期产生的短生命周期子进程,父进程只管生成,不处理子进程退出后的状态,导致系统积累大量僵死进程。解决方法包括通过信号机制让子进程向父进程发送SIGCHILD信号,以及在fork两次中将子进程变为孤儿进程,由init进程处理僵尸进程。
孤儿进程测试程序:通过循环创建子进程验证孤儿进程的存在。
僵尸进程测试程序:创建子进程,让其退出,观察系统中是否存在僵尸进程。
僵尸进程测试2:循环创建子进程,子进程退出后,检查僵尸进程数量。
僵尸进程解决办法:通过信号机制让子进程向父进程发送SIGCHILD信号,或在fork两次中让子进程成为孤儿进程,由init进程处理僵尸进程。
杀死Linux中的defunct进程僵尸进程的方法指南
这篇文章主要介绍了杀死Linux中的defunct进程(僵尸进程)的方法指南,文中首先对defunct进程的概念和运作方式作了补充说明,需要的朋友可以参考下
一、什么是defunct进程(僵尸进程)
在 Linux系统中,一个进程结束了,但是他的父进程没有等待(调用wait/ waitpid)他,那么他将变成一个僵尸进程。当用ps命令观察进程的执行状态时,看到这些进程的状态栏为defunct。僵尸进程是一个早已死亡的进程,但在进程表(processs table)中仍占了一个位置(slot)。
但是如果该进程的父进程已经先结束了,那么该进程就不会变成僵尸进程。因为每个进程结束的时候,系统都会扫描当前系统中所运行的所有进程,看看有没有哪个进程是刚刚结束的这个进程的子进程,如果是的话,就由Init进程来接管他,成为他的父进程,从而保证每个进程都会有一个父进程。而Init进程会自动wait其子进程,因此被Init接管的所有进程都不会变成僵尸进程。
二、 Linux下进程的运作方式
每个 Linux进程在进程表里都有一个进入点(entry),核心进程执行该进程时使用到的一切信息都存储在进入点。当用 ps命令察看系统中的进程信息时,看到的就是进程表中的相关数据。当以fork()系统调用建立一个新的进程后,核心进程就会在进程表中给这个新进程分配一个进入点,然后将相关信息存储在该进入点所对应的进程表内。这些信息中有一项是其父进程的识别码。
子进程的结束和父进程的运行是一个异步过程,即父进程永远无法预测子进程到底什么时候结束。那么会不会因为父进程太忙来不及 wait子进程,或者说不知道子进程什么时候结束,而丢失子进程结束时的状态信息呢?
不会。因为 Linux提供了一种机制可以保证,只要父进程想知道子进程结束时的状态信息,就可以得到。这种机制就是:当子进程走完了自己的生命周期后,它会执行exit()系统调用,内核释放该进程所有的资源,包括打开的文件,占用的内存等。但是仍然为其保留一定的信息(包括进程号the process ID,退出码exit code,退出状态the terminationstatus of the process,运行时间the amount of CPU time taken by the process等),这些数据会一直保留到系统将它传递给它的父进程为止,直到父进程通过wait/ waitpid来取时才释放。
也就是说,当一个进程死亡时,它并不是完全的消失了。进程终止,它不再运行,但是还有一些残留的数据等待父进程收回。当父进程 fork()一个子进程后,它必须用 wait()(或者 waitpid())等待子进程退出。正是这个 wait()动作来让子进程的残留数据消失。
三、僵尸进程的危害
如果父进程不调用wait/ waitpid的话,那么保留的那段信息就不会释放,其进程号就会一直被占用,但是系统的进程表容量是有限的,所能使用的进程号也是有限的,如果大量的产生僵尸进程,将因为没有可用的进程号而导致系统不能产生新的进程。
所以,defunct进程不仅占用系统的内存资源,影响系统的性能,而且如果其数目太多,还会导致系统瘫痪。而且,由于调度程序无法选中Defunct进程,所以不能用kill命令删除Defunct进程,惟一的方法只有重启系统。
四、如何杀死defunct进程
defunct进程是指出错损坏的进程,父子进程之间不会再通信。有时,它们会演变成“僵尸进程”,存留在你的系统中,直到系统重启。可以尝试“kill-9”命令来清除,但多数时候不管用。
为了杀死这些defunct进程,你有两个选择:
1.重启你的计算机
2.继续往下读...
我们先看看系统中是否存在defunct进程:
复制代码代码如下:
$ ps-A| grep defunct
假设得到的输出如下所示:
复制代码代码如下:
8328? 00:00:00 mono
8522? 00:00:01 mono
13132? 00:00:00 mono
25822? 00:00:00 ruby
28383? 00:00:00 ruby
18803? 00:00:00 ruby
这意味着存在6个defunct进程:3个mono进程,以及3个ruby进程。这些进程之所以存在,可能是因为应用程序写得很烂或者用户做了不常见的操作,在我这,一定是我写的mono C#程序存在严重问题:smile:。
现在,我们来看看这些进程的ID及其父进程ID:
复制代码代码如下:
$ ps-ef| grep defunct| more
以上命令的输出如下:
复制代码代码如下:
UID PID PPID...
---------------------------------------------------------------
kenno 8328 6757 0 Mar22? 00:00:00 [mono]
kenno 8522 6757 0 Mar22? 00:00:01 [mono]
kenno 13132 6757 0 Mar23? 00:00:00 [mono]
kenno 25822 25808 0 Mar27? 00:00:00 [ruby]
kenno 28383 28366 0 Mar27? 00:00:00 [ruby]
kenno 18803 18320 0 Apr02? 00:00:00 [ruby]
UID:用户ID
PID:进程ID
PPID:父进程ID
如果你使用命令“kill-9 8328”尝试杀死ID为8328的进程,可能会没效果。要想成功杀死该进程,需要对其父进程(ID为6757)执行kill命令($ kill-9 6757)。对所有这些进程的父进程ID应用kill命令,并验证结果($ ps-A| grep defunct)。
如果前一个命令显示无结果,那么搞定!否则,可能你需要重启一下系统。
僵尸进程僵尸进程是怎样产生的
在Linux操作系统中,当一个进程调用exit命令结束其生命周期时,实际上并不会立即消失,而是留下一种特殊的状态,被称为僵尸进程(Zombie)。exit命令的作用仅是让一个正常进程转变为僵尸进程,而非完全销毁。僵尸进程在进程状态中具有独特性,它们释放了大部分内存空间,不再包含可执行代码,也无法被调度。它们在进程列表中保留一个位置,记录着退出状态等信息,以便供其他进程获取。
僵尸进程的清理过程依赖于其父进程。如果父进程没有安装SIGCHLD信号处理函数,或者没有通过wait或waitpid方法等待子进程结束,又没有忽略该信号,那么子进程将一直处于僵尸状态。在这种情况下,如果父进程结束,系统中的init进程会接手处理,清理僵尸进程。然而,如果父进程是一个持续运行的循环,僵尸进程就会长期存在,导致系统中有时会出现大量未被清理的僵尸进程。
要检查系统中是否存在僵尸进程,可以使用ps命令,其中标记为Z的进程即为僵尸进程。通过这种方式,系统管理员可以追踪和管理这些特殊状态的进程。
扩展资料
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来接管他,成为他的父进程……