2014-01-07 39 views
0

我有以下代碼,其中父母創建多個子進程並在之後將其殺死。一旦遇害,我想打印什麼殺死了孩子(在這種情況下是信號)。但是,代碼不打印。什麼似乎是問題?如何讓孩子打印殺死它的信號?

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <string.h> 
#include <signal.h> 
#include <sys/types.h> 
#include <sys/wait.h> 

int i; 

static void signal_handler(int signo) 
{ 
    if (signo == SIGUSR1) 
    { 
    printf("child %d received sigusr1\n", i + 1); 
    } 
} 

int main(void) 
{ 
    char buff[50]; 
    int status; 

    if (signal(SIGUSR1, signal_handler) == SIGUSR1) 
    { 
    perror("Signal handling error"); 
    } 

    pid_t cpid, count; 

    for (i = 0; i < 5; i++) 
    { 
    cpid = fork(); 

    if (cpid == 0) 
    { 
     sleep(10); 

     //exit(0); 
    } 
    else if (cpid > 0) 
    { 
     kill(cpid, SIGUSR1); 
     int status; 
     int n = waitpid(cpid, &status, 0); 

     if (n != cpid) 
     { 
     perror("error"); 
     } 

     if (WIFSIGNALED(status)) 
     { /* get WTERMSIG(status) */ 
     printf("killed by signal=%d\n", WTERMSIG(status)); 
     } 
    } 
    else 
    { 
     perror("Fork error: "); 
     exit(1); 
    } 
    } 
} 
+0

嗯 - 我想在父母的殺人信號到達之前,孩子們終止並退出(0)。應讓兒童保持活躍與睡眠(),所以他們仍然在SIGUSR信號到達。 – user422005

+0

我試過,但它仍然沒有打印這部分: printf(「殺死信號=%d \ n」); WTERMSIG(status); – user3015353

回答

0

使用waitpid代替,並且一定要處理正常退出並殺害按信號:

pid_t pid = fork(); 

if (pid == 0) 
{ 
    exit(0); 
} 
else if (pid > 0) 
{ 
    int status; 
    int n = waitpid(pid, &status, 0); 

    if (n != pid)     { /* error */ } 
    else if (WIFSIGNALED(status)) { /* get WTERMSIG(status) */ } 
    else if (WIFEXITED(status)) { /* get WEXITSTATUS(status) */ } 
} 
else if (pid < 0) 
{ 
    /* error */ 
} 

你可以從文檔中看到,wait將等待任何孩子,不只是現在的孩子。當然,在接收信號之前,孩子完全有可能正常退出。

你可以通過調用pause來阻止孩子正常退出,但是如果不是得到處理,信號將只會殺死孩子。如果信號處理程序返回,則返回pause

+0

我如何確保孩子只因信號而死亡? – user3015353

+0

@ user3015353:讓孩子不出口,例如無限期地睡眠。 –

+0

@ user3015353:或者在子中調用'pause'。 –

0

這是你的應用程序的實際代碼?

printf("killed by signal=%d\n"); 
WTERMSIG(status); 

如果是這樣,第二行有沒有效果,嘗試將其更改爲:

printf("killed by signal=%d\n", WTERMSIG(status)); 
+0

我已經發布了編輯版本,你可以請看看它。 '被信號殺死'的行仍然沒有被打印 – user3015353

+0

正如@duck所提出的那樣,我刪除了信號處理程序,現在'信號行'被打印出來了。感謝您的幫助。 – user3015353

1

WIFSIGNALED(stat_val) - 如果狀態是爲孩子返回值是一個非零值過程要在收到未被捕獲

你的信號的信號終止由於被抓(當他們再在他們退出之前先行通過)。

您有別人提到的其他問題。

+0

謝謝你的回答。 – user3015353