在UNIX术语中,一个已经终止、但是其父进程尚未对其进行善后处理(获取终止子进程的有关信息、释放它仍占用的资源)的进程被称为僵尸进程(zombie)。
僵尸进程出现的条件:
子进程先结束,且父进程没有wait
如何杀掉僵尸进程:
僵尸进程本身不能使用kill杀掉,但可以kill 其父进程,此时僵尸进程将会被init进程收养,从而消除僵尸进程.(1号进程本身例wait子进程)
僵尸进程的避免:
一,让父进程比子进程先结束,让init进程来领养子进程。
比如可以fork 2次:A进程 fork出B子进程,B子进程再fork出C子进程,再杀掉B子进程。这样C子进程就由init进程领养了。
一个由init进程领养的进程终止时会发生什么?它会不会变成一个僵尸进程?对此问题的回答是“否”,因为init被编写成只要有一个子进程终止,init就会调用一个wait函数取得其终止状态。这样也就防止了在系统中有很多僵尸进程。当提及“一个init的子进程”时,这指的是init直接产生的进程,或者是其父进程已终止,由init领养的进程。
二,父进程使用waitpid等待子进程返回.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(void)
{
pid_t pid;
if ((pid = fork()) < 0)
{
puts("fisrt fork error");
exit(1);
}
if (pid == 0) //first child
{
if ((pid = fork()) < 0)
{
puts("second fork error");
exit(1);
}
if (pid == 0) // second child
{
sleep(2);
printf("The second child pid :%d ---- My parent: %d \n", getpid(), getppid());
exit(0);
}
else // second fork 's child 's parent == first child
{
printf("The first child pid :%d ---- My parent: %d \n", getpid(), getppid());
exit(0);
}
}
if (pid != waitpid(pid, NULL, 0))
{
printf("wait error.\n");
}
printf("My pid :%d ---- My parent: %d \n", getpid(), getppid());
exit(0);
}