关于Linux僵尸进程,一般是由于子进程结束的时候,会有一些资源没有释放掉,直到父进程结束或者由父进程去处理它才可以!
僵尸进程就是子进程已经结束,但是父进程没有处理的进程!
父进程可以使用waitpid,wait等来处理僵尸进程!
if 父进程不幸在子进程之前“死了”,那么子进程就交由init( pid == 1 )进程去管理~
我们可以测试以下:
具体的程序解释看代码的注释!
#include <stdio.h> #include <stdlib.h> #include<sys/types.h> int main() { int status; if(!fork()) //!> fork一个进程 { printf("child pid=%d\n", getpid()); exit(0); } printf("请输入ps -e : 查看僵尸进程!\n"); sleep(10); //!> 让你有时间去输入ps -e查看 printf("下面让父进程wait,来处理僵尸进程,请再ps -e查看! \n"); if( waitpid(-1, &status, 0) != -1 ) //!> 参数是-1就是等待所有的子进程 { printf( "子进程退出status:%d\n", status ); } else { printf("waitpid error!\n"); exit( 1 ); } sleep(10); //!> 让你有时间去输入ps -e查看 exit(0); }
gcc -o 1 1.c
我的机子上运行结果:
2747 pts/0 00:00:00 bash
2768 pts/0 00:00:00 1 //!> 看:这个就是父进程
2769 pts/0 00:00:00 1 <defunct> //!> 看:这个就是子进程成为僵尸进程
2772 pts/1 00:00:00 bash
2802 pts/1 00:00:00 ps
pengtao@ubuntu:~$
//!> 10s 之后我打开第二个终端ps -e
2747 pts/0 00:00:00 bash
2768 pts/0 00:00:00 1 //!> 没有咯~~~呵呵~~~
2772 pts/1 00:00:00 bash
2805 pts/2 00:00:00 bash
2821 pts/2 00:00:00 ps
pengtao@ubuntu:~$
当然我们可以使用忽略信号,使得不产生僵尸进程!
signal( SIGCHLD, SIG_IGN ); //!> 忽略产生僵尸进程
#include <stdio.h> #include <stdlib.h> #include<sys/types.h> #include <signal.h> int main() { int status; int i; signal( SIGCHLD, SIG_IGN ); //!> 忽略产生僵尸进程 for( i = 0; i < 5; i++ ) //!> 5个子进程 { if(!fork()) { printf("child pid=%d\n", getpid()); exit(0); } } printf("请输入ps -e : 查看僵尸进程!\n"); sleep(10); exit(0); }
gcc -o 1 1.c
3115 pts/0 00:00:00 bash
3172 pts/1 00:00:00 bash
3228 pts/0 00:00:00 1
3237 pts/1 00:00:00 ps
所以一般情况下if需要子进程的结果来做一些判断 ,那么我们应该是需要wait或waitpid的,但是很多时候是可以直接忽略的,对于僵尸进程来说,消耗的src虽然少,但是一旦僵尸建成多了也是会影响性能的,所以还是需要注意的!