当父进程在子进程退出后没有使用wait系统调用来读取其退出状态时,将会创建出一个僵尸进程;而孤儿进程则是指当原始父进程在子进程之前终止,init将回收该子进程。
在内存管理和进程表方面,这些进程在UNIX中是如何处理的?
有哪些例子或极端情况,会对整个应用程序或系统造成僵尸进程或孤儿进程的创建有害?
当父进程在子进程退出后没有使用wait系统调用来读取其退出状态时,将会创建出一个僵尸进程;而孤儿进程则是指当原始父进程在子进程之前终止,init将回收该子进程。
在内存管理和进程表方面,这些进程在UNIX中是如何处理的?
有哪些例子或极端情况,会对整个应用程序或系统造成僵尸进程或孤儿进程的创建有害?
孤儿进程是指其父进程
已经完成或终止,但它(子进程)仍然在运行。
僵尸进程或者称为“死进程”,是一种已经完成执行但由于其父进程没有调用wait()
系统调用而在进程表中仍然存在的进程。
孤儿进程 - 当父进程退出时,初始化进程成为子进程的父进程。 每当子进程终止时,操作系统都会删除进程表。
僵尸进程 - 当子进程终止时,它会向父进程发送退出状态。 与此同时,假设您的父进程处于睡眠状态,并且无法接收来自子进程的任何状态。 虽然子进程已经退出,但是该进程在进程表中占用空间。
在 Linux Ubuntu 中执行此命令 >> ps -eo pid,ppid,status,cmd
如果您发现最后一行有defunc,即表示您的进程处于僵尸状态并且正在占用空间。
僵尸进程: 已经执行完毕但仍有一条记录在进程表中向其父进程报告的进程称为僵尸进程。子进程被从进程表中移除之前,通常会先变成僵尸进程。父进程读取子进程的退出状态并清除进程表中该子进程的条目。
孤儿进程: 其父进程不存在了,即已经完成或终止而没有等待其子进程结束的进程称为孤儿进程。
仅在使用PID 1的进程中才存在孤儿进程。
从正在运行的进程的角度来看,它是否直接启动并因此具有PID 1作为父进程或者被PID 1继承(因为其原始父进程与PID 1不同)而获得PID 1,对于它来说没有区别。它像任何其他进程一样处理。
每个进程在结束时都会经历某种僵尸状态,即在发出SIGCHLD
并且已经确认其处理(传递或忽略)之间的阶段。
当进入僵尸状态时,该进程只是系统进程列表中的一个条目。
僵尸进程独占的唯一重要资源是有效的PID。
我想添加两个代码片段,分别涉及孤儿进程和僵尸进程。但首先,我将发布在Silberschatz、Galvin和Gagn的书“操作系统概念”中所述的这些进程的定义:
如果没有父进程等待(未调用wait())进程,则为 僵尸进程
如果父进程终止而没有调用wait,则该进程是一个孤儿进程
// 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;
}
输出
我的父进程不等我
我不等待我的子进程
编辑:参照并灵感来自这里
摘要
init
进程接管。wait()
系统调用来清除僵尸进程,它确保父进程在子进程完成之前不执行或空闲等待。孤儿进程会发生什么?
init
进程(pid=1)。这称为重新分配父进程。来源:
已经执行完毕但仍然在进程表中保留有条目向其父进程报告的进程被称为僵尸进程。如果父进程不存在,即已完成或终止而没有等待其子进程终止,则称为孤儿进程。
最初的回答:
僵尸进程是指已经执行完毕但仍然在进程表中保留有条目向其父进程报告的进程。孤儿进程则是指父进程不存在,即已完成或终止而没有等待其子进程终止的进程。