2014-04-14 47 views
1

我從SE QUE得到以下信息 明確將SIGCHLD的處置設置爲SIG_IGN會導致後續終止的任何子進程立即從系統中刪除而不是轉換成殭屍。不想立即刪除終止的子進程,需要成爲殭屍

據我所知,讀它需要在進程表子PID孩子的狀態。所以有必要讓殭屍子進程在進程表中讀取子進程的狀態。

所以我想寫的信號處理程序,這將刪除「設置SIGCHLD的配置爲SIG_IGN」

我用下面的代碼(前叉),以避免終止後立即清除子進程:但我仍然感到不能夠通過ECHILD獲得孩子狀態和waitpid回報-1。

#include <errno.h> 
#include <signal.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <unistd.h> 

static siginfo_t sig_info; 
static volatile sig_atomic_t sig_num; 
static void *sig_ctxt; 

static void catcher(int signum, siginfo_t *info, void *vp) 
{ 
    sig_num = signum; 
    sig_info = *info; 
    sig_ctxt = vp; 
} 

static void set_handler(int signum) 
{ 
    struct sigaction sa; 
    sa.sa_flags = SA_SIGINFO; 
    sa.sa_sigaction = catcher; 
    sigemptyset(&sa.sa_mask); 

    if (sigaction(signum, &sa, 0) != 0) 
    { 
     int errnum = errno; 
     fprintf(stderr, "Failed to set signal handler (%d: %s)\n", errnum, strerror(errnum)); 
     exit(1); 
    } 
} 

static void prt_interrupt(FILE *fp) 
{ 
    if (sig_num != 0) 
    { 
     fprintf(fp, "Signal %d from PID %d\n", sig_info.si_signo, (int)sig_info.si_pid); 
     sig_num = 0; 
    } 
} 

請建議一些想法,我與此阻止。

+2

如果你讀等待(2)的說明,你會看到明確設置SIG_IGN導致兒童的直接收割。但是,默認操作也是「忽略」不會執行此操作。因此,要獲得殭屍,所有你需要做的就是** **不設置CIGCHLD或者,據我所知,將其設置爲SIG_DFL的信號作用。 – DoxyLover

+0

如何不設置SIGCHLD或AFAIK的信號作用?將它設置爲SIG_DFL?你能否提供樣本實施鏈接? – kapilddit

+1

只需**不**設置SIGCHLD的處理程序!在你展示的代碼中,永遠不要調用set_handler(SIGCHLD)。我可以從個人經驗告訴你,如果你不使用SIGCHLD猴子,你會得到殭屍。 – DoxyLover

回答

0

相反捕捉信號的,只是使用此代碼在主:

signal(SIGCHLD,SIG_IGN); 

而不是使用該處理程序的,使用SIG_IGN(如上所示)。這將忽略該信號,並且過程PID將留在處理表,則可以.Parent()權利要求這個殭屍過程的狀態使用waitpid函數或等待()。

+0

這是錯誤的。使用調用信號(SIGCHLD,SIG_IGN)顯式忽略SIGCHLD將使被終止的進程自動從進程表中刪除(至少在內核2.6上)。請參閱waitpid的註釋部分。如果您希望他們留在桌子上,只需保留默認的信號處理程序。 –