定义:
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)他, 那么他将变成一个僵尸进程. 在fork()/execve()过程中,假设子进程结束时父进程仍存在,
而父进程fork()之前既没安装SIGCHLD信号处理函数调用waitpid()等待子进程结束,又没有显式忽略该信号,则子进程成为僵尸进程。
如何查看linux系统上的僵尸进程,如何统计有多少僵尸进程?
#ps -ef | grep defunct
或者查找状态为Z的进程,Z就是代表zombie process,僵尸进程的意思。
另外使用top命令查看时有一栏为S,如果状态为Z说明它就是僵尸进程。
Tasks: 95 total, 1 running, 94 sleeping, 0 stopped, 0 zombie
top命令中也统计了僵尸进程。或者使用下面的命令:
ps -ef | grep defunct | grep -v grep | wc -l
如何杀死僵尸进程呢?
一般僵尸进程很难直接kill掉,不过您可以kill僵尸爸爸。父进程死后,僵尸进程成为”孤儿进程”,过继给1号进程init,init始终会负责清理僵尸进程.它产生的所有僵尸进程也跟着消失。
ps -e -o ppid,stat | grep Z | cut -d” ” -f2 | xargs kill -9
或
kill -HUP `ps -A -ostat,ppid | grep -e ’^[Zz]‘ | awk ’{print $2}’`
另外子进程死后,会发送SIGCHLD信号给父进程,父进程收到此信号后,执行waitpid()函数为子进程收尸。就是基于这样的原理:就算父进程没有调用wait,内核也会向它发送SIGCHLD消息,而此时,尽管对它的默认处理是忽略(?待定,个人感觉默认是不忽略吧!),如果想响应这个消息,可以设置一个处理函数。
如何避免僵尸进程呢?
处理SIGCHLD信号并不是必须的。但对于某些进程,特别是服务器进程往往在请求到来时生成子进程处理请求。如果父进程不等待子进程结束,子进程将成为僵尸进程(zombie)从而占用系统资源。如果父进程等待子进程结束,将增加父进程的负担,影响服务器进程的并发性能。在Linux下 可以简单地将 SIGCHLD信号的操作设为SIG_IGN。
signal(SIGCHLD,SIG_IGN);
这样,内核在子进程结束时不会产生僵尸进程。这一点与BSD4不同,BSD4下必须显式等待子进程结束才能释放僵尸进程
或者
用两次fork(),而且使紧跟的子进程直接退出,使得孙子进程成为孤儿进程,从而init进程将负责清除这个孤儿进程。
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Linux的僵尸进程及其解决方法
1. 产生原因:
在UNIX 系统中,一个进程结束了,但是他的父进程没有等待(调用wait /waitpid)他,那么他将变成一个僵尸进程。通过ps命令查看其带有defunct的标志。僵尸进程是一个早已死亡的进程,但在进程表(processs table)中仍占了一个位置(slot)。
但是如果该进程的父进程已经先结束了,那么该进程就不会变成僵尸进程。因为每个进程结束的时候,系统都会扫描当前系统中所运行的所有进程,看看有没有哪个进程是刚刚结束的这个进程的子进程,如果是的话,就由Init进程来接管他,成为他的父进程,从而保证每个进程都会有一个父进程。而Init进程会自动wait其子进程,因此被Init接管的所有进程都不会变成僵尸进程。
2. 原理分析:
每个Unix进程在进程表里都有一个进入点(entry),核心进程执 行该进程时使用到的一切信息都存储在进入点。当用 ps 命令察看系统中的进程信息时,看到的就是进程表中的相关数据。当以fork()系统调用建立一个新的进程后,核心进程就会在进程表中给这个新进程分配一个 进入点,然后将相关信息存储在该进入点所对应的进程表内。这些信息中有一项是其父进程的识别码。
子进程的结束和父进程的运行是一个异步过程,即父进程永远无法预测子进程到底什么时候结束。那么会不会因为父进程太忙来不及 wait 子进程,或者说不知道子进程什么时候结束,而丢失子进程结束时的状态信息呢?不会。因为UNIX提供了一种机制可以保证,只要父进程想知道子进程结束时的状态信息,就可以得到。这种机制就是:当子进程走完了自己的生命周期后,它会执行exit()系统调用,内核释放该进程所有的资源,包括打开的文件,占用的内存等。但是仍然为其保留一定的信息(包括进程号the process ID,退出码exit code,退出状态the terminationstatus of the process,运行时间the amount of CPU time taken by the process等),这些数据会一直保留到系统将它传递给它的父进程为止,直到父进程通过wait / waitpid来取时才释放。
3.解决方法:
(1) 父进程通过wait和waitpid等函数等待子进程结束,这会导致父进程挂起。
执行wait()或waitpid()系统调用,则子进程在终止后会立即把它在进程表中的数据返回给父进程,此时系统会立即删除该进入点。在这种情形下就不会产生defunct进程。
(2) 如果父进程很忙,那么可以用signal函数为SIGCHLD安装handler。在子进程结束后,父进程会收到该信号,可以在handler中调用wait回收。
(3) 如果父进程不关心子进程什么时候结束,那么可以用signal(SIGCLD, SIG_IGN)或signal(SIGCHLD, SIG_IGN)通知内核,自己对子进程的结束不感兴趣,那么子进程结束后,内核会回收,并不再给父进程发送信号
(4)fork两次,父进程fork一个子进程,然后继续工作,子进程fork一个孙进程后退出,那么孙进程被init接管,孙进程结束后,init会回收。不过子进程的回收还要自己做。
分享到:
相关推荐
### 僵尸(zombie)进程详解与处理方法 #### 一、僵尸进程定义与状态 在Linux系统中,进程可以处于多种不同的状态,而其中一种特殊的状态被称为“僵尸”状态(Z)。当一个进程终止时,其父进程应当通过`wait()`或`...
僵尸进程是计算机操作系统中的一种特殊状态,当一个进程执行完毕并退出,但其父进程尚未读取其退出状态时,这个已结束的进程就会成为僵尸进程。它的主要特征是进程已不再执行任何代码,但其进程描述符仍然存在于内存...
在Linux系统中,僵尸进程(Zombie Process)是一种常见的系统问题,它们通常是由父进程创建的子进程在完成任务后未能被父进程正确回收而遗留下来的。这些僵尸进程虽然不再执行任何操作,但仍然占据着系统资源,如...
有些ZOMBIE进程时用kill -9也不能杀死,而且消耗了很多系统资源不能释放,如果系统在shutdown时发出信息:some process wouldn’t die。这就意味着有些进程不能被reboot发出的kill –9杀掉,这些很可能就是僵尸进程...
在Linux操作系统中,僵尸进程(Zombie Process)是一种特殊状态的进程,它的产生与操作系统的进程生命周期管理和资源回收机制紧密相关。当一个进程执行完毕并退出时,内核并不会立即清除该进程的所有信息,而是将其...
7. **Z (Defunct or Zombie)**:僵尸状态。进程已经终止,但其父进程尚未调用`wait()`系统调用来清理子进程的资源。僵尸进程会占用一定的系统资源,但不消耗CPU时间。 #### 扩展状态标记 除了上述基本状态外,在...
4. zombie 进程:用于学习僵尸进程的概念。例如,输入 zombie.c 文件,编译和运行后,可以学习僵尸进程的基本概念。 5. ps 命令:用于显示当前系统中的进程列表。例如,输入 ps -ax 命令,可以显示当前系统中的进程...
进程状态包括运行(Running)、就绪(Ready)、睡眠(Sleeping)和僵尸(Zombie)等。当进程在等待CPU资源时,它是就绪状态;正在执行的进程处于运行状态;睡眠状态通常是因为进程在等待某些事件发生,如I/O操作完成...
RUNNING进程可能正在运行或等待调度,INTERRUPTIBLE进程在等待资源时可以被信号唤醒,而STOPPED进程用于调试,ZOMBIE进程已结束但未完全清除。 理解并掌握这些知识点对于深入学习Linux系统管理和编程至关重要,因为...
- **僵尸进程**(Zombie Process):是已经结束但其父进程尚未调用 `wait()` 或 `waitpid()` 函数进行清理的进程。僵尸进程的存在仅仅是因为它们的父进程没有正常地清理它们的资源,它们的状态被标记为 “ZOMBIE”,...
6. **僵尸态(Zombie)**:进程已终止,但父进程尚未回收其资源。 #### 进程调度 Linux采用多种调度策略,如完全公平调度器(CFS,Completely Fair Scheduler),基于进程的优先级和实时性需求进行调度。调度依据...
5. **TASK_ZOMBIE(僵尸状态)**:进程已退出,但父进程尚未调用`wait`函数获取其退出状态。 ##### 2.2 进程调度策略 Linux进程调度策略主要分为两大类:实时进程调度和非实时进程调度。 1. **实时进程调度**:...
### Linux 守护进程(Daemon Process)与僵尸进程(Zombie Process) #### 一、守护进程(Daemon Process) 守护进程是Linux系统中的一个重要概念,它是一种后台运行的进程,主要负责执行特定的任务或提供某种服务...
- **僵尸(Zombie)**:进程已终止但其父进程尚未读取其退出状态,这时进程会变为僵尸状态。 - **终止(Dead)**:进程完全终止,等待系统回收资源。 #### 3. 进程间通信(IPC) Linux提供了多种进程间通信(IPC...
- **僵尸状态 (Zombie)**:进程已经结束,但其父进程尚未对其进行清理。这类进程只保留了PID和退出状态等少量信息,不会占用CPU资源,但会影响系统性能。 - **退出状态 (Exit)**:进程已完成所有工作,即将被系统...
进程生命周期包括就绪(ready)、运行(running)、睡眠(sleep)、停止(stopped)和僵死(zombie)等状态。在Linux中,进程调度通常由调度器(scheduler)负责,其采用优先级和时间片轮转等算法来决定进程获得CPU...
- Linux中,进程有五种状态:运行(TASK_RUNNING)、可中断睡眠(TASK_INTERRUPTIBLE)、不可中断睡眠(TASK_UNINTERRUPTIBLE)、暂停(TASK_STOPPED)和僵尸状态(TASK_ZOMBIE)。 - 进程状态转换通常发生在系统...
5. **僵尸状态(Zombie)**:子进程结束但父进程尚未读取其退出状态时的状态。 #### 进程状态转换 进程状态之间可以通过一系列系统调用来进行转换: - 当一个进程从就绪状态变为运行状态时,通常是因为它获得了...
TASK_ZOMBIE(僵尸状态),进程已结束但未完全释放资源;以及TASK_STOPPED(暂停状态),需接收信号才能继续执行。 Linux的调度方式基于"有条件的可剥夺"原则,即普通进程在时间片结束时会被自愿调度,而实时进程在...