пример сигнала убивания - PullRequest
5 голосов
/ 09 июня 2011

Я пробую этот пример, который я взял: http://www.cs.cf.ac.uk/Dave/C/node24.html:

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

void sighup(); /* routines child will call upon sigtrap */
void sigint();
void sigquit();

main() { 
 int pid;

 /* get child process */

 if ((pid = fork()) < 0) {
    perror("fork");
    exit(1);
 }

if (pid == 0) { /* child */
   printf("\nI am the new child!\n\n");
       signal(SIGHUP,sighup); /* set function calls */
       signal(SIGINT,sigint);
       signal(SIGQUIT, sigquit);
       printf("\nChild going to loop...\n\n");
      for(;;); /* loop for ever */
 }
else /* parent */
 {  /* pid hold id of child */
   printf("\nPARENT: sending SIGHUP\n\n");
   kill(pid,SIGHUP);
   sleep(3); /* pause for 3 secs */
   printf("\nPARENT: sending SIGINT\n\n");
   kill(pid,SIGINT);
   sleep(3); /* pause for 3 secs */
   printf("\nPARENT: sending SIGQUIT\n\n");
   kill(pid,SIGQUIT);
   sleep(3);
 }
}

void sighup() {
   signal(SIGHUP,sighup); /* reset signal */
   printf("CHILD: I have received a SIGHUP\n");
}

void sigint() {
    signal(SIGINT,sigint); /* reset signal */
    printf("CHILD: I have received a SIGINT\n");
}

void sigquit() {
  printf("My DADDY has Killed me!!!\n");
  exit(0);
}

Но я не вижу выходных данных дочернего процесса.

Это ожидаемое поведение? Если так; почему?

Большое спасибо!

Ответы [ 2 ]

2 голосов
/ 09 июня 2011

Ваш код имеет основное состояние гонки. Вы не гарантируете, что ребенок завершил вызов signal до того, как родитель отправит сигналы. Либо нужно использовать какой-то примитив синхронизации, чтобы родительский элемент ожидал, пока дочерний объект установит обработчики, либо вам нужно установить обработчики сигналов перед разветвлением, чтобы дочерний объект унаследовал их.

Вот самый простой способ, которым я знаю для синхронизации процессов, подобных этому:

  1. Перед разветвлением вызовите pipe(p), чтобы создать канал.
  2. fork().
  3. В родительском close(p[1]); (конец письма) и read(p[0], &dummy, 1);
  4. У ребенка close(p[0]); и close(p[1]); после установки обработчиков сигналов.
  5. Когда родитель возвращается из read, вы можете быть уверены, что ребенок настроил свои обработчики сигналов. На этом этапе вы также можете close(p[0]); у родителя.

Редактировать 2: Возможно, лучший и более простой подход:

  1. Перед разветвлением позвоните sigprocmask, чтобы заблокировать все сигналы и сохранить старую маску сигналов.
  2. В родительском файле снова вызовите sigprocmask сразу после разветвления, чтобы восстановить исходную маску сигнала.
  3. У ребенка, позвоните sigprocmask сразу после установки обработчиков сигналов, чтобы восстановить исходную маску сигналов.
0 голосов
/ 03 июня 2017

Вы должны использовать getpid () вместо pid ().

...