进程正常退出步骤
- 子进程调用exit() 函数退出
- 父进程通过wait()函数获取子进程的退出状态,并且把子进程所占用的进程控制块销毁掉。
- 如果进程没有正常退出的话,可能会产生僵尸进程或者托孤进程。
僵尸进程
子进程退出后,父进程并没有调用wait() 函数来获取退出状态,那么子进程就变成了僵尸进程。
下面是测试程序
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<unistd.h>
int main()
{
int pid;
if((pid = fork()) < 0)
{
perror("Faile to fork.\n");
return -1;
}
else if(0 == pid)
{
printf("Child exits now.\n");
exit(0);
}
else
{
while(1);
//此为父进程。
//并没有调用wait()函数。
}
return 0;
}
测试结果
jl@jl-virtual-machine:~/test/11_1$ gcc dd.c
jl@jl-virtual-machine:~/test/11_1$
jl@jl-virtual-machine:~/test/11_1$ ls
a.out dd.c
jl@jl-virtual-machine:~/test/11_1$
jl@jl-virtual-machine:~/test/11_1$ ps aux | grep a.out
jl 2281 101 0.0 4380 796 pts/0 R 19:01 0:27 ./a.out
jl 2282 0.0 0.0 0 0 pts/0 Z 19:01 0:00 [a.out] <defunct>
jl 2284 0.0 0.0 16180 1148 pts/0 S+ 19:01 0:00 grep --color=auto a.out
jl@jl-virtual-machine:~/test/11_1$
可以看到有一个 Z,表示僵尸态,该行是子进程。此时父进程仍然在运行。
托孤进程
父进程比子进程先退出,则子进程变为孤儿进程,os将子进程托孤给1号进程(pid=1,又叫init进程),由这个1号进程在子进程exit()时接收子进程的返回状态,并负责销毁子进程所占用的进程控制块。