2012-09-14 67 views
2

我對c和編程非常陌生,需要一些幫助。在linux上(cygwin)我需要在出口處刪除所有子進程。我已經看過其他類似的問題,但無法使其工作。我試過了 -父進程出口處殺死子進程

atexit(killzombies); //in parent process 

void killzombies(void) 
{ 
    printf("works"); 
    kill(0, SIGTERM); 
    printf("works"); 
    if (waitpid(-1, SIGCHLD, WNOHANG) < 0) 
     printf("works"); 
} 

由於某些原因,「作品」甚至沒有打印過。我按ctrl + c退出。

我也有tried-

prctl(PR_SET_PDEATHSIG, SIGHUP); //in child process 
signal(SIGHUP, killMe); 

void killMe() 
{ 
    printf("works"); 
    exit(1); 
} 

,但因爲我使用Cygwin的,當我#include <sys/prctl.h>,cygwin的說,它無法找到文件或目錄,我不知道要安裝的軟件包它。 另外,如果我的prctl()函數可以工作,那會殺死所有的殭屍嗎?

我的程序是一個客戶端服務器和我的服務器forks()來處理每個客戶端。我想在服務器關閉時不會留下殭屍。

+0

一個鏈接,你可以看到http://www.faqs.org/faqs/unix-faq/faq/part3/section-13.html。特別是最後的解決方案這對你有用嗎? –

回答

0

atexit(3) Linux文檔:使用atexit()(和on_exit(3))註冊

函數不叫,如果 一個進程異常終止,因爲信號的傳遞的。

如果您希望在應用程序收到SIGINT或SIGTERM時進行清理,則需要安裝相應的信號處理程序並在那裏完成您的工作。

1

您的waitpid不提供通常的參數,我很驚訝它不會崩潰。原型爲:

pid_t waitpid(pid_t pid, int *status, int options); 

第二個參數應該是一個指針int,你是供給int。 另請注意,您應該撥打waitpid每個孩子,你只能稱它爲一個。

atexit()僅在正常退出時調用。如果通過CTRL + C退出,則需要從SIGINT上的處理程序調用您的函數。

0

你需要跟蹤你的進程有多少孩子,然後多次呼叫等待。另外,正如其他人所說的,如果進程被信號終止,則不會調用您的atexit()函數,因此您還需要從信號處理函數中調用killzombies()。你需要這樣的東西:

int n_children = 0; // global 

void handle_sig(int sig) { 
    killzombies(); 
    exit(sig); 
} 

// your atexit() 
void killzombies() { 
    kill(0, SIGKILL); 
    while (n_children > 0) { 
     if (wait(NULL) != -1) { 
      n_children--; 
     } 
    } 
}