僵死进程:一个进程执行结束,但是进程的PCB没有被系统释放。进程结束后,还要在PCB中保存ji进程退出码,以备其父进程获取。
实例:父进程未结束,子进程结束,并且父进程没有获取子进程的退出码。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>
#include <string.h>
int main()
{
pid_t pid = fork();
assert(-1 != pid);
if(pid == 0)
{
printf("child start\n");
sleep(10);
printf("child end\n")
}
else
{
printf("father start\n");
sleep(20);
printf("father end\n");
}
exit(0);
}
在前十秒钟,父、子进程正常运行,输出father start、child start
在10~20秒钟:子进程运行时间到,ps后我们发现此时子进程已经是僵死进程
20秒后,父进程执行完毕,直接退出。但是子进程还没有退出。此时子进程就是孤儿进程,就需要系统出面,将子进程挂在到init下面去。
如何处理僵死进程:
就是让父进程获取子进程的退出状态:
pid_t wait(int *status);
status:获取的进程的退出码
返回处理的进程的PID
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>
#include <string.h>
int main()
{
pid_t pid = fork();
assert(-1 != pid);
if(pid == 0)
{
printf("child start:%d\n",getpid());
sleep(10);
printf("child end\n")
}
else
{
pid_t id = wait(NULL);
printf("id = %d\n",id);
printf("father start\n");
sleep(20);
printf("father end\n");
}
exit(0);
}
输出结果:
首先,wait的返回确实和子进程的PID相同,都是6463.
然后我们看到,父进程开始运行是在子进程退出之后才开始的。
所以,wait在这里会做这样的事:本身会阻塞,直到有子进程退出。
但是,系统中的主进程一般都是父进程,那么使用wait就会造成必须把所有的子进程处理完成才会运行父进程,所以效果不好。
在这里还可以使用waitpid方法,效果更好,请自行查阅。