Процесс умирает после сигнала SIGINT - PullRequest
0 голосов
/ 14 октября 2018

Я не понимаю, что здесь происходит, у меня есть родительский процесс, который обрабатывает сигнал SIGINT, а затем делает его дочерним.Когда я нажимаю ^ C, я ожидаю, что оба процесса напечатают «SIGINT полученный», а затем продолжат, но оказывается, что родительский процесс умирает после получения SIGINT, но дочерний процесс все еще там.Я не могу этого понять.

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

void handler (int sig) {
  printf("SIGINT received\n");
}

void child() {
  while (1) {
    printf("I'm the child\n");
    sleep(1);
  }

  exit(0);
}

int main(int argc, char *argv[]) {
  struct sigaction act;

  memset(&act, 0, sizeof(act));

  act.sa_handler = &handler;
  // Link SIGINT with the handler
  sigaction(SIGINT, &act, NULL);

  // Create child
  if (fork() == 0) child();

  wait(NULL);

  return 0;
}

Пример выполнения:

$ ./test_signals
I'm the child
^CSIGINT received
I'm the child
SIGINT received
$ I'm the child
I'm the child

Таким образом, оба процесса обрабатывают SIGINT, но родитель умирает, а потом продолжает ...

1 Ответ

0 голосов
/ 14 октября 2018

Родительский процесс блокируется в основной функции и при получении сигнала обрабатывает его и возвращается с вызовом на wait с ошибкой.

Дочерний цикл просто обрабатывает whileSIGINT.Когда обработанный код возвращается туда, где он был (вероятно, заблокирован во сне), и он продолжает цикл.

Этот код может иллюстрировать, что происходит:

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

void handler (int sig) {
  printf("SIGINT received %d\n",getpid());
}

void child() {
  while (1) {
    printf("I'm the child\n");
    sleep(1);
  }

  exit(0);
}

int main(int argc, char *argv[]) {
  struct sigaction act;

  memset(&act, 0, sizeof(act));

  act.sa_handler = &handler;
  // Link SIGINT with the handler
  sigaction(SIGINT, &act, NULL);

  // Create child
  if (fork() == 0) child();

  int r = wait(NULL);
  if (r==-1 && errno==EINTR) printf("signal probably received in parent\n");

  return 0;
}

Имейте в виду, что вызов printf вобработчик сигнала запрещен.

...