Zombie process 僵尸进程及孤儿进程简介( 二 )


严格地来说,僵死进程并不是问题的根源,罪魁祸首是产生出大量僵死进程的那个父进程 。因此,当我们寻求如何消灭系统中大量的僵死进程时,答案就是把产生大 量僵死进程的那个元凶枪毙掉(也就是通过kill发送或者信号啦) 。枪毙了元凶进程之后,它产生的僵死进程就变成了孤儿进 程,这些孤儿进程会被init进程接管,init进程会wait()这些孤儿进程,释放它们占用的系统进程表中的资源,这样,这些已经僵死的孤儿进程 就能瞑目而去了 。
3.僵尸进程解决办法 1)通过信号机制
子进程退出时向父进程发送信号,父进程处理信号 。在信号处理函数中调用wait进行处理僵尸进程 。测试程序如下所示:
#include #include #include #include #include static void sig_child(int signo);int main(){pid_t pid;//创建捕捉子进程退出信号signal(SIGCHLD,sig_child);pid = fork();if (pid < 0){perror("fork error:");exit(1);}else if (pid == 0){printf("I am child process,pid id %d.I am exiting.\n",getpid());exit(0);}printf("I am father process.I will sleep two seconds\n");//等待子进程先退出sleep(2);//输出进程信息system("ps -o pid,ppid,state,tty,command");printf("father process is exiting.\n");return 0;}static void sig_child(int signo){pid_tpid;intstat;//处理僵尸进程while ((pid = waitpid(-1, &stat, WNOHANG)) >0)printf("child %d terminated.\n", pid);}
测试结果如下所示:
2)fork两次
《Unix 环境高级编程》8.6节说的非常详细 。原理是将子进程成为孤儿进程,从而其的父进程变为init进程,通过init进程可以处理僵尸进程 。测试程序如下所示:
#include #include #include #include int main(){pid_tpid;//创建第一个子进程pid = fork();if (pid < 0){perror("fork error:");exit(1);}//第一个子进程else if (pid == 0){//子进程再创建子进程printf("I am the first child process.pid:%d\tppid:%d\n",getpid(),getppid());pid = fork();if (pid < 0){perror("fork error:");exit(1);}//第一个子进程退出else if (pid >0){printf("first procee is exited.\n");exit(0);}//第二个子进程//睡眠3s保证第一个子进程退出,这样第二个子进程的父亲就是init进程里sleep(3);printf("I am the second child process.pid: %d\tppid:%d\n",getpid(),getppid());exit(0);}//父进程处理第一个子进程退出if (waitpid(pid, NULL, 0) != pid){perror("waitepid error:");exit(1);}exit(0);return 0;}
【Zombie process僵尸进程及孤儿进程简介】测试结果如下所示: