ChinaUnix.net
 >> ChinaUnix.net > Solaris

怎么彻底的杀僵尸(defunct)进程?

作者:wyhan     发表时间:2002/08/25 11:34am

我公司的邮件服务器是UNIX系统,这段时间不能正常的收发邮件,有ps -ef看进程时发现有大量的僵尸(defunct)进程,只有重起。可是挨不到一上午,就又不能收发邮件了。看进程还是看到好多的僵尸(defunct)进程。那只有在重起了。可这不是解决的办法。能告诉我怎么处理这个僵尸(defunct)进程,才能让系统正常的运行。

此文章相关评论:
该文章有3个相关评论如下:(点这儿可以发表评论)
jsn 发表于: 2002/08/25 01:42pm
[这个贴子最后由jsn在 2002/08/25 01:48pm 编辑]

父进程在fork出子进程后,如果子进程死了,父进程没有给它收尸,就会产生僵尸进程。要杀死僵尸进程,只有两个办法:

1、改写父进程,在子进程死后要为它收尸。具体做法是接管SIGCHLD信号。子进程死后,会发送SIGCHLD信号给父进程,父进程收到此信号后,执行waitpid()函数为子进程收尸。

2、把父进程杀掉。父进程死后,它产生的所有僵尸进程也跟着消失。


以solaris为例:


// 在父进程中接管SIGCHLD信号
   newact.sa_handler = Quit;
   newact.sa_flags   = 0;
   newact.sa_handler = WaitChld;// WaitChld为SIGCHLD信号处理函数名
   sigemptyset(&newact.sa_mask);
   sigaction(SIGCHLD, &newact, NULL);

// WaitChld函数

void WaitChld(int sig)
{
   char    szRtnMsg[128];
   int     status, chld_term_sig;
   pid_t   pid;

   pid = waitpid(0, &status, WNOHANG);

   if (WIFEXITED(status) != 0)     // 子进程正常退出
       return;

   strcpy(szRtnMsg, "子进程异常终止");

   chld_term_sig = WTERMSIG(status);
   switch (chld_term_sig) {
   case SIGILL:
   case SIGTRAP:
   case SIGABRT:
   //case SIGEMT:
   case SIGFPE:
   case SIGBUS:
   case SIGSEGV:
   //case SIGSYS:
   case SIGXCPU:
       strcat(szRtnMsg, "(CoreDumped)");
       break;

   case SIGQUIT:
   case SIGKILL:
   case SIGTERM:
       strcat(szRtnMsg, "(Killed)");
       break;

   default:
       break;
   }
}

 
zhangrp 发表于: 2002/08/25 03:53pm
真够复杂的,看来学习不好好看书不行。
 
wyhan 发表于: 2002/08/25 05:34pm
谢谢楼上兄弟告诉我方法。
 
 

Copyright © ChinaUnix.net  *  转载请注明出处及作者