僵尸进程

1. 概念:   

    在fork()/execve()过程中,假设子进程结束时父进程仍存在,而父进程fork()之前既没安装SIGCHLD信号处理函数调用waitpid()等待子进程结束,又没有显式忽略该信号,则子进程成为僵尸进程,无法正常结束,此时即使是root身份kill -9也不能杀死僵尸进程。补救办法是杀死僵尸进程的父进程(僵尸进程的父进程必然存在),僵尸进程成为"孤儿进程",过继给1号进程init,init始终会负责清理僵尸进程.

 

2. 本质:

    所谓以root身份也不能杀死僵尸进程,其实只是用户态的感觉。真正原因是这个进程在内核看来已经结束了,你不能杀死一个死人,不是吗。内核维护了一些状态信息,等待其父进程获取这些状态信息,除非父进程明确表示它不想获取这些状态信息。

 

3. 处理:

  • 显式忽略SIGCHLD信号是指类似这样的代码:
signal( SIGCHLD, SIG_IGN );

 

  • 安装SIGCHLD信号句柄是指类似这样的代码:
static   void  on_sigchld (  int  signo ) 
   

       pid_t pid; 
       
int   status; 
    
       
while ( ( pid = waitpid( -1&status, WNOHANG ) ) > 0 ) 
       

           
/* 
            * 演示用,不推荐在信号句柄中使用fprintf() 
            
*/
 
           fprintf( stderr, 
"child <%u> terminated", ( unsigned int )pid ); 
       }
 
       
return
   }
   /* end of on_sigchld */  
   ... ... 
   signal( SIGCHLD, on_sigchld ); 

当然,我们不建议使用signal(),应该使用sigaction()。 

 

原文地址: http://edu.stuccess.com/knowcenter/Unix/16/newcata/00000139.htm
 

你可能感兴趣的:(僵尸进程)