// A C program to demonstrate Orphan Process.
// Parent process finishes execution while the
// child process is running. The child process
// becomes orphan.
#include <stdio.h> //printf
#include <stdlib.h> //exit
#include <sys/types.h> //fork
#include <unistd.h> //fork and sleep
int main()
{
// Fork returns process id
// in parent process
pid_t child_pid = fork();
// Parent process didn't use wait and finished before child
// so the child becomes an orphan process
// Parent process
if (child_pid > 0) {
printf("I finished my execution before my child");
}
else // Child process
if (child_pid == 0) {
sleep(1); //sleep for 1 second
printf("This printf will not be executed");
}
else{
//error occurred
}
return 0;
}
产出**
我在我的孩子之前完成了死刑 僵尸
// A C program to demonstrate Zombie Process.
// Child becomes Zombie as parent is not waiting
// when child process exits.
#include <stdio.h> //printf
#include <stdlib.h> //exit
#include <sys/types.h> //fork
#include <unistd.h> //fork and sleep
int main()
{
// Fork returns process id
// in parent process
pid_t child_pid = fork();
// Parent process didn't use wait
// so the child becomes a zombie process
// Parent process
if (child_pid > 0){
sleep(1); //sleep for 1 second
printf("\nI don't wait for my child");
}
else // Child process
if(child_pid == 0){
printf("My parent doesn't wait me");
exit(0);
}
else{
//error occurred
}
return 0;
}
9条答案
按热度按时间vq8itlhq1#
当一个子进程退出时,某个进程必须对其执行
wait
操作以获取它的退出代码。在此之前,退出代码一直存储在进程表中。阅读退出代码的行为称为“收割”子进程。从子进程退出到被收割,这段时间称为僵尸进程。(当您仔细想想时,整个术语有点可怕;我建议不要想太多。)僵尸进程只占用进程表中的空间。它们不占用内存或CPU。然而,进程表是一个有限的资源,过多的僵尸进程可以填满它,这意味着没有其他进程可以启动。除此之外,它们是令人烦恼的混乱,应该强烈避免。
如果一个进程退出时子进程仍在运行(并且没有杀死它的子进程;比喻继续离奇),那些孩子就是孤儿。孤儿马上就被
init
“收养”了(其实我想大多数人都把这叫做“再养育”,但“收养”似乎更能承载这个比喻)。孤儿只是一个过程,它用什么资源就用什么资源。按理说,它根本不是“孤儿”,因为它有父母,但我经常听到他们这么叫。init
自动收割它的孩子(收养的或其他的)。所以如果你没有清理你的孩子就退出了,那么他们不会变成僵尸(至少不会超过一分钟)。但是长寿的僵尸是存在的。他们是什么?他们是一个现有进程的前子进程,而这个进程还没有收获他们。这个进程可能被挂起了。或者它可能写得很差,忘记了收获它的子进程。或者它可能过载了,还没有抽出时间来处理它。或者其他什么。但是出于某种原因,父进程继续存在(因此它们不是孤儿),并且它们没有被服务,因此它们在进程表中作为僵尸继续存在。
因此,如果您看到僵尸的时间超过了一分钟,那么这意味着父进程有问题,应该做一些事情来改进该程序。
sbdsn5lh2#
当一个进程终止时,它的资源将被操作系统释放。但是,它在进程表中的条目必须保持在那里,直到父进程调用等待(),因为进程表包含进程的退出状态。已终止但其父进程尚未调用wait的进程(),被称为僵尸进程。所有进程在终止时都会转换到这种状态,但通常它们只是短暂地作为僵尸存在。(),则释放僵尸进程的进程标识符及其在进程表中的条目。
现在考虑如果父进程不调用wait会发生什么(),而不是终止,从而使其子进程成为孤儿。Linux和UNIX通过将init进程指定为孤儿进程的新父进程来解决此问题。init进程定期调用wait(),从而允许收集任何孤立进程的退出状态,并释放孤立进程的标识符和进程表条目。
来源:* 操作系统概念 * 作者:Abraham、Peter、Greg
roejwanj3#
孤儿进程是
parent process
已完成或终止的计算机进程,但它(子进程)仍在运行自己。僵尸进程或失效进程是指已完成执行但在进程表中仍有条目的进程,因为其父进程未调用
wait()
系统调用。gzszwxb44#
孤儿-父进程退出,初始进程成为子进程的父进程。每当子进程终止时,进程表被操作系统删除。
僵尸-当子进程终止时,它会将退出状态发送给父进程。同时,假设父进程处于睡眠状态,无法从子进程接收任何状态。虽然子进程退出,但进程占用进程表中的空间
在linux ubuntu〉〉ps -eo pid,ppid,status,cmd中检查这个命令
如果你在最后发现了类似defunc的东西,也就是说你的进程是僵尸进程,并且占用了空间。
ncgqoxb05#
**僵尸进程:**已完成执行但在进程表中仍有一个条目要报告给其父进程的进程称为僵尸进程。子进程在从进程表中删除之前总是首先成为僵尸进程。父进程读取子进程的退出状态,子进程从进程表中获取子进程条目。
**孤儿进程:**一个进程的父进程不再存在,即完成或终止,而没有等待其子进程终止,这被称为孤儿进程。
qlckcl4x6#
1.除了使用PID 1的进程外,没有孤立进程。
从运行进程的Angular 来看,它是直接启动的,因此以PID 1作为父进程,还是因为它的原始父进程(不同于PID 1)结束而被PID 1继承,都没有区别。
1.每个进程在结束时都会经历某种僵尸状态,即从发出
SIGCHLD
宣布结束到确认其处理(交付或忽略)之间的阶段。当进入僵尸状态时,进程只是系统进程列表中的一个条目。
僵尸独占使用的唯一重要资源是有效的PID。
jfewjypa7#
我想添加两个代码片段,分别描述一个孤儿进程和一个僵尸进程。但首先,我将发布Silberschatz,Galvin和Gagn在《操作系统概念》一书中对这些进程的定义:
如果没有正在等待的父进程(未调用wait()),则进程为僵尸进程
如果父进程在未调用等待的情况下终止,则进程为孤立进程
孤儿
我在我的孩子之前完成了死刑
僵尸
我父母不等我
我不等我的孩子
编辑:来源和灵感来自here
w1jd8yoj8#
一个进程如果已经完成了执行,但进程表中仍有条目要向其父进程报告,则称为僵尸进程。一个进程如果其父进程不再存在,即完成或终止,而没有等待其子进程终止,则称为孤儿进程
nwo49xxi9#
下面是一个总结
| 僵尸进程|孤立进程|
| - ------|- ------|
| 僵尸进程是指已完成任务但仍在进程表中显示一个条目的进程。|如果子进程在其父进程终止或完成后仍在运行,而不等待子进程执行,则该子进程称为孤立进程。|
| 僵尸进程状态始终由Z指示|孤立进程是由于系统崩溃而无意中创建的。|
| 僵尸进程被视为死亡进程,它们不用于系统处理|孤儿进程是一个计算机进程,即使在它的父进程终止后,它仍成为父进程并继续执行剩余的任务。|
|
wait()
系统调用用于处理僵尸进程|内核分配一个新进程作为孤儿进程的父进程,通常这个新的父进程是init
进程(pid = 1)。|| 要删除僵尸进程,请执行
kill
命令。|使用SIGHUP
信号终止孤立进程。|资料来源: