首先我们来先了解一下什么是僵尸进程和孤儿进程?
当你创建了子进程后,让父子进程干不同的事,如果,子进程先完成事情要退出时,然后它就会等‘人’来读取它的退出状态信息(也就是他的父进程),这个时候,子进程就需要一直维持这这个状态,这个状态就是僵尸状态(我们也称为Z状态)。也就是说,当一个子进程退出时,他的父进程还没有退出,它就会一直等待父进程来读取它的退出信息,这个时候子进程就处于僵尸状态。
那么如果,是父进程先干完自己的事呢?当父进程先退出,子进程还没有退出,那么这个子进程就会成为一个‘孤儿’进程,那么这个子进程的信息一定得有一个进程来读取,则该子进程会被init进程(进程id为1 的那个进程,我们经常叫他一号进程)领养,当它退出时,也由init进程读取它的退出信息。
这里再谈谈僵尸进程,当子进程先退出时,它必须要等父进程来接收它的信息,告诉父进程它把工作完成的怎么样了,这个时候它还占有PCB资源,在父进程没来之前,它要一直占有资源,维持保存它的信息。我们试想,如果僵尸进程比较多,那么势必会有资源的浪费,也存在资源泄露的问题,其实很糟糕的。
下面就来实现僵尸进程和孤儿进程:
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
int main()
{
pid_t id=fork();
if(id==0)
{//子进程先退出
printf("i am child! pid:%d ppid:%d\n",getpid(),getppid());
}
else if(id>0){
sleep(5);
printf("i am father!pid:%d ppid:%d\n",getpid(),getppid());
}
else
perror("fork false");
return 0;
}
在Linux实现结果:
孤儿进程:
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
int main()
{
pid_t id=fork();
if(id==0)
{
sleep(8);
printf("i am child! pid:%d ppid:%d\n",getpid(),getppid());
}
else if(id>0){//父进程先退出
printf("i am father!pid:%d ppid:%d\n",getpid(),getppid());
}
else
perror("fork false");
return 0;
}
在Linux下运行结果:可见,子进程被1号进程领养了。