如何在“mongoose webserver”(Linux)上处理/杀死Zombie或<defunct>进程cgi脚本(C ++)?</defunct>

时间:2011-08-08 18:10:10

标签: c linux unix webserver mongoose-web-server

我在Ubuntu 10.04上使用C ++编写的“mongoose webserver”上运行了一个CGI脚本(独立于mongoose特定的API,以便于将来的可移植性)。每当我从网络浏览器(Chrome)调用脚本时,该过程都可以正常运行,但是当我运行ps -al时,我看到了

F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
4 S     0  3567  8877  0  80   0 - 23309 hrtime pts/0    00:00:00 mongoose
4 Z     0  3585  3567  7  80   0 -     0 exit   pts/0    00:00:00 test <defunct>

在这种情况下,我使用sudo kill -9 3567来终止父进程。我的脚本中有以下代码。

...
#include <sys/wait.h>
...

//==========================================================================
// Define the function to be called when ctrl-c (SIGINT) signal is sent to process
static void signal_callback_handler(int signum)
{ 
    point_of_inspection( __FILE__, __func__, __LINE__, ENABLE_LOG); // Entered the routine

    // Cleanup and close up stuff here
    while(1)
    {
        if (signum == SIGTERM)
        {
            error_log_report("caught signal - premature exit",CAUGHT_SIGNAL_ERROR,ENABLE_LOG);
            break;
        }
    }
    clean_exit();
    // Terminate program
    exit(signum);
}
//======================= Zombies or <defunct> handler ========================
// Signal handler to process terminated children
static void mysig(int nsig) 
{ 
    int nStatus, nPid; 
    while(1)
    {
        if (nsig == SIGCHLD)
        {
            nPid = waitpid(-1, &nStatus, WNOHANG); 
            if(nPid<0)
            {
                error_log_report("waitpid (nPid<0)",CAUGHT_SIGNAL_ERROR,ENABLE_LOG);         
                break;               
            }
            if(nPid==0)
            {
                error_log_report("Caught Signal - Zombies <defunct> (nPid==0)",CAUGHT_SIGNAL_ERROR,ENABLE_LOG);
                break;  
            }
        } 
    }
    clean_exit();
    exit(nsig);
} 

在主要功能

 int main()
 {
  //some initialization variables
  ...

     // Register signal and signal handler
     signal(SIGTERM, signal_callback_handler);

     // To clean up terminated children
     signal(SIGCHLD, mysig); 
  ...

     return 0;
 }

然而,当用户关闭网页浏览器或导航到不同的页面时似乎没有捕获任何信号,因为我没有看到任何日志。我想知道这是不是mongoose或我的脚本中的错误(我的脚本中没有使用任何fork()进程或线程。但是mongoose确实使用了线程。而且我的脚本中没有使用任何mongoose webserver特定的API。) 。

我在这里引用信号教程http://orchard.wccnet.org/~chasselb/linux275/ClassNotes/process/sigbasics.htmhttp://www.gnu.org/s/hello/manual/libc/Process-Completion.html

2 个答案:

答案 0 :(得分:1)

他们更新了 mongoose.c 文件中的代码以获取僵尸。以下是代码的一部分。

#if !defined(_WIN32) && !defined(__SYMBIAN32__)
  // Ignore SIGPIPE signal, so if browser cancels the request, it
  // won't kill the whole process.
  (void) signal(SIGPIPE, SIG_IGN);
  // Also ignoring SIGCHLD to let the OS to reap zombies properly.
  (void) signal(SIGCHLD, SIG_IGN);
#endif // !_WIN32

答案 1 :(得分:0)

Unix中的僵尸进程是由父进程终止但尚未等待的进程。他们的存在应该是暂时的,或者表示父母的错误,在本案例中mongoose