2015-10-14 3 views
0

Я пытаюсь передать дочерний процесс пустой сигнал (SIGUSR1) от родителя. Насколько я знаю, я правильно настроил сигнал. Я чувствую, что я возился с вызовом функции Kill(). Я ожидаю какую-то печатную продукцию, но ничего не получаю. Не изнутри ребенка, ни из самой сигнальной функции.Функция сигнала, не вызываемая

код:

void my_handler(int signum); 

int main() 
{ 
    pid_t pid; 

    if((pid = fork()) == -1) 
    { 
    printf("Error on fork().\n"); 
    exit(1); 
    } 

    if(pid == 0) 
    { 
    if(signal(SIGUSR1, my_handler)) 
    { 
    printf("+1"); 
    } 
    } 
    else if(pid > 0) 
    { 
    sleep(2); 
    kill(pid, SIGUSR1); 
    } 

} 

void my_handler(int signum) 
{ 
    if (signum == SIGUSR1) 
    { 
     printf("Received SIGUSR1!\n"); 
    } 
} 
+1

Сделайте себе одолжение: проверьте возвращаемые значения из системных вызовов, например 'kill()'. Они говорят, работает ли система, или нет. –

+0

Выполнение этого сейчас. –

+0

Ваш дочерний процесс выходит, как только он установил обработчик сигнала. Он не ждет получения сигнала. – kaylum

ответ

2

Вы ребенок выходит, прежде чем посылается сигнал:

if(pid == 0) 
    { 
    if(signal(SIGUSR1, my_handler)) 
    { 
    printf("+1"); 
    } 
    } 
    else if(pid > 0) 
    { 
    sleep(2); 
    kill(pid, SIGUSR1); 
    } 

Ребенок может печатать +1, но затем он выходит. Между тем, ваш родитель ждет две секунды, чтобы убедиться, что ребенок действительно мертв, а затем отправляет ему сигнал. Его нет!

Чтобы исправить: добавьте какой-то код, который заставляет ребенка зависать, чтобы получить сигнал. Простейшим, вероятно, является pause();, хотя sleep() будет работать более 2 секунд.

Необходимо проверить системные вызовы. Например:

if (kill(pid, SIGUSR1) != 0) 
{ 
    fprintf(stderr, "kill(%d) failed: %d %s\n", (int)pid, errno, strerror(errno)); 
    exit(1); 
} 

Вы быстро надоедает с написанием 4 строки кода, так что вы в конечном итоге с функцией, которая сообщает о системной ошибке и завершает работу (с помощью С11 _Noreturn):

void _Noreturn err_syserr(const char *fmt, ...) 
{ 
    int errnum = errno; // Capture it before it changes 
    va_list args; 
    va_start(args, fmt); 
    vfprintf(stderr, fmt, args); 
    va_end(args); 
    if (errno != 0) 
     fprintf(stderr, "%d: %s\n", errnum, strerror(errnum)); 
    exit(1); 
} 

Использование:

if (kill(pid, SIGUSR1) != 0) 
    err_syserr("kill(%d) failed: ", (int)pid); 

(Не все согласны с печатью номер ошибки, вы платите деньги и сделайте ваш выбор.)

См. Также How to avoid using printf in a signal handler? Это не часть вашей проблемы, но вы должны знать о проблемах.

3

дочерний процесс завершает работу до того, как родительский процесс имеет возможность послать сигнал к нему. Попробуйте добавить sleep(5) в дочерний процесс после звонка signal.

+0

"* Попробуйте добавить' sleep (5) '.. . * "или просто вызовите' pause() '. – alk

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

  • Нет связанных вопросов^_^