孤儿进程:
-
父进程先于子进程结束,则子进程成为孤儿进程,子进程的父进程成为init进程,称为init进程领养孤儿进程。
孤儿进程其实对于操作系统来说是没有太大的危害,在孤儿进程中父进程结束了之后,子进程就被init进程领养了,这时候我们不需要去管理我们的子进程,init进程会自动的释放我们子进程的资源,不会导致我们的资源浪费
导致孤儿进程我们可以看到下面代码所产生的结果
//orphan.c 孤儿进程演示
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
int main(void)
{
pid_t pid;
pid = fork();
if (pid == 0) {
while (1) {
printf("I am child, my parent pid = %d\n", getppid());
sleep(1);
}
} else if (pid > 0) {
printf("I am parent, my pid is = %d\n", getpid());
sleep(9);
printf("------------parent going to die------------\n");
} else {
perror("fork");
return 1;
}
return 0;
}
- 僵尸进程
僵尸进程: 进程终止,父进程尚未回收,子进程残留资源(PCB)存放于内核中,变成僵尸(Zombie)进程。
【zoom .c】
特别注意,僵尸进程是不能使用kill命令清除掉的。因为kill命令只是用来终止进程的,而僵尸进程已经终止。为什么会导致僵尸进程呢?
僵尸进程导致原因:
子进程先于父进程退出,退出原因保存在PCB中,操作系统检测到进程退出后,通过父进程进行回收,但是此时父进程可能没有关注到我们子进程已经退出了,这时候操作系统不会随意的去释放我们的子进程资源,此时我们的子进程已经退出,但是我们的资源却没有被回收。此时我们的子进程就是一个Z(将死态)也就是我们称为 的僵尸进程
一下代码就是产生了僵尸进程
#include <stdio.h>
#include <unistd.h>
int main(){
pid_t pid = fork();
if(pid == 0){
printf("i am child\n");
sleep(3);
printf("i die\n");
}else{
while(1){
printf("i am father\n");
sleep(5);
}
}
}
产生的结果就是导致了僵尸进程。
所以在进程中我们应该去避免产生僵尸进程,如果过多的产生了僵尸进程,我们的资源泄漏严重,达到了进程数量的上限之后我们就不能再创建新的进程。
解决方案:
- 使用wait相关函数去回收子进程
- 杀死父进程
- 使用信号SIGCHLD来释放我们的子进程资源