目录
一、孤儿进程
1.什么是孤儿进程
孤儿进程:一个父进程退出,而它的一个或多个子进程还在运行,那么这些子进程将成为孤儿进程。孤儿进程将被 init 进程(进程号为1,也被称为守护进程)所收养,并由 init 进程对它们完成状态收集工作。
2.孤儿进程的危害
孤儿进程是没有父进程的进程,孤儿进程这个重任就落到了 init 进程(守护进程)身上。每当出现一个孤儿进程的时候,内核就把孤儿进程的父进程设置为 init,而 init 进程会循环地 wait() 它的已经退出的子进程。这样,当一个孤儿进程结束时,init 进程就会出面处理它的退出信息。因此孤儿进程并不会有什么危害。
二、僵死进程
1.什么是僵死进程
僵死进程:一个进程使用 fork 创建子进程,如果子进程退出,而父进程并没有调用 wait 或 waitpid 获取子进程的状态信息,那么子进程的进程描述符仍然保存在系统中,这种进程称之为僵死进程。
2.僵死进程的危害
僵死进程虽然不占有任何内存空间,但如果父进程不调用 wait() / waitpid() 的话,那么保留的信息就不会释放,其进程号就会一直被占用,而系统所能使用的进程号是有限的,如果大量的产生僵死进程,将因为没有可用的进程号而导致系统不能产生新的进程,此即为僵死进程的危害。
3.如何解决僵死进程
-
父进程使用wait 和 waitpid 等函数等待子进程结束;
-
被init收养
4.wait()使用
wait()
在wait()使用行阻塞,等待子进程结束,但如此会阻塞父进程,可用信号进行优化。
获取子进程退出码
int val; wait(&val); //获取子进程退出信息
WIFEIXTED(val) //判断是否获得退出信息,即是否正常退出
WEXITSTATUS(val) //返回退出码
编写测试代码,对进程退出码进行获取:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
int main()
{
char* s = NULL;
int n = 0;
pid_t id = fork();
if (id == -1)
{
exit(1);
}
if (id == 0)
{
s = "child";
n = 3;
}
else
{
s = "parent";
n = 7;
int val = 0;
wait(&val);
if (WIFEXITED(val))
{
printf("exit code : %d\n", WEXITSTATUS(val));
}
}
for (int i = 0; i < n; i++)
{
printf("s = %s, curr_pid = %d, curr_ppid = %d, &n = %p, n = %d\n", s, getpid(), getppid(), &n, n);
sleep(1);
}
exit(0);
}
输出结果: