Linux 僵尸进程 ( Zombie or defunct )

关于Linux僵尸进程,一般是由于子进程结束的时候,会有一些资源没有释放掉,直到父进程结束或者由父进程去处理它才可以!

            僵尸进程就是子进程已经结束,但是父进程没有处理的进程!

            父进程可以使用waitpid,wait等来处理僵尸进程!

            if 父进程不幸在子进程之前“死了”,那么子进程就交由init( pid == 1 )进程去管理~

           

            我们可以测试以下:

            具体的程序解释看代码的注释!

           

  1. #include <stdio.h>   
  2. #include <stdlib.h>   
  3. #include<sys/types.h>   
  4.   
  5. int main()  
  6. {  
  7.     int status;  
  8.       
  9.     if(!fork())    //!> fork一个进程   
  10.     {  
  11.             printf("child pid=%d\n", getpid());  
  12.         exit(0);  
  13.     }  
  14.   
  15.     printf("请输入ps -e : 查看僵尸进程!\n");  
  16.       
  17.     sleep(10);    //!> 让你有时间去输入ps -e查看   
  18.   
  19.     printf("下面让父进程wait,来处理僵尸进程,请再ps -e查看! \n");  
  20.   
  21.     if( waitpid(-1, &status, 0) != -1 )     //!> 参数是-1就是等待所有的子进程   
  22.     {  
  23.         printf( "子进程退出status:%d\n", status );  
  24.     }  
  25.     else  
  26.     {  
  27.         printf("waitpid error!\n");  
  28.         exit( 1 );  
  29.     }  
  30.       
  31.     sleep(10);   //!> 让你有时间去输入ps -e查看   
  32.     exit(0);  
  33. }  
#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 );        //!> 忽略产生僵尸进程

          

           

  1. #include <stdio.h>   
  2. #include <stdlib.h>   
  3. #include<sys/types.h>   
  4. #include <signal.h>   
  5.   
  6. int main()  
  7. {  
  8.     int status;  
  9.     int i;  
  10.       
  11.     signal( SIGCHLD, SIG_IGN );     //!> 忽略产生僵尸进程   
  12.       
  13.     for( i = 0; i < 5; i++ )     //!> 5个子进程   
  14.     {  
  15.         if(!fork())  
  16.         {  
  17.             printf("child pid=%d\n", getpid());  
  18.             exit(0);  
  19.         }  
  20.     }  
  21.   
  22.     printf("请输入ps -e : 查看僵尸进程!\n");  
  23.       
  24.     sleep(10);  
  25.      
  26.         exit(0);  
  27. }  
#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虽然少,但是一旦僵尸建成多了也是会影响性能的,所以还是需要注意的!

原文地址:https://www.cnblogs.com/xyz123753/p/2609788.html