1. 孤儿进程
父进程结束,但子进程未结束,此时子进程变成孤儿进程(Orphan Process)。
内核会将init进程(pid=1)设置为孤儿进程的父进程。init进程会循环调用wait函数回收已退出的孤儿进程。
可以说孤儿进程无危害。
孤儿进程示例:
#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<stdlib.h>
int main(int argc, const char* argv[]) {
pid_t pid = -1;
pid = fork();
if (-1 == pid) {
perror("fork");
return 1;
}
if (pid > 0) { // 父进程
sleep(1);
printf("父进程结束.\n");
exit(0);
}
while (1) { // 子进程
printf("子进程运行中,其父进程为%d.\n", getppid());
sleep(1);
}
return 0;
}
运行结果:
2. 僵尸进程
父进程未回收已退出子进程的资源,则子进程残留资源(PCB)会存放于内核,子进程变成僵尸进程(Zombie Process)。
僵尸进程会占用系统资源,有危害。
僵尸进程示例:
#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<stdlib.h>
int main(int argc, const char* argv[]) {
pid_t pid = -1;
pid = fork();
if (pid == 0) { // 子进程
exit(0); // 子进程结束
}
// 父进程,未使用wait或waitpid回收子进程资源
getchar();
return 0;
}
运行后,查看僵尸进程(STAT为Z+):
如何处理僵尸进程?
(1)使用ps或top命令查看僵尸进程的信息,找到它们父进程pid,使用kill -9命令杀死父进程,然后僵尸进程变成孤儿进程被init接管回收;
(2)kill -HUP命令挂起僵尸进程,让它们不再占用系统资源;
(3)父进程中调用wait或waitpid避免僵尸进程。