2014-01-07 2 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) до того, как сигнал смерти от родителя прибывает. Следует держать детей в живых, например. с sleep(), чтобы они все еще находились вокруг сигнала SIGUSR. – user422005

+0

Я пробовал это, но его еще не печатал эту часть: printf («убит сигналом =% d \ n»); WTERMSIG (статус); – 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

Смежные вопросы