僵尸进程:
僵尸状态:子进程退出后父进程要知道子进程是正常退出还是异常退出以及原因还有它处理结果,则这个进程退出后先保存其PCB,然后父进程检测其状态,检测完之后子进程,回收其资源然后子进程退出状态。而子进程退出后父进程没有检测的这个时间段则为僵尸状态也就是这个时间段是僵尸进程。
僵尸进程:一个子进程在其父进程没有调用wait或waitpid()下退出。这个子进程就成为了僵尸进程。
僵尸进程的测验:
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
int main()
{
pid_t id = fork();
if ( id < 0 ){
printf("fork error! return code is : %d\n",errno);//创建子进程失败返回
return 2;
}
else if( 0 == id ){ //child
printf("child pid is : %d, father pid is : %d\n", getpid(), getppid());//返回自己的id和父进程的id
exit(3);//令子进程先退出这是父进程没有wait或者waitpid()则子进程成为僵尸进程
}
else{ //father
printf("father pid is : %d\n", getpid());
sleep(5);//父进程先sleep5秒在退出这样保证了子进程现推出。
}
system("ps -o pid,ppid,state,tty,command");
return 0;
}
僵尸进程不能太多,否则占用的内存资源过多但是不能被回收造成了内存泄漏的问题。
孤儿进程:
孤儿进程:一个父进程退出,而它的的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程。孤儿进程将会被init进程(进程号为1)所收养,并由init进程对它们完成状态收集工作。
孤儿进程测试:
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
int main(int argc, char **argv[])
{
int id = fork();
if(id < 0)
{
printf("fork error\n");
exit(3);
}
else if ( id > 0 ) {
printf("father id is: %d\n", getpid());
sleep(3);
exit(0);//让其父进程运行3秒直接退出此时子进程还在运行
}
else
{
printf("Child id is: %d\n, father id is: %d", getpid(), getppid());
sleep(5);
}
system("ps -o pid,ppid,state,tty,command");
return 0;
}
从面的图中可以看出吗,在父进程没有退出之前子进程的父进程还是4069,而父进程退出之后子进程的父进程为1号进程了(也就是init进程 )。