简体   繁体   中英

Process dies after SIGINT signal

I don't understand what is happening here, I have a parent process which handles the SIGINT signal and then makes a child. What I expect when I press Ctrl + C is that both processes will print "SIGINT received" and then continue but it turns out that the parent process dies after receiving SIGINT but the child is still there. I can't understand that.

#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;
}

An example of execution:

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

So both processes handle SIGINT but the parent dies while the child continues...

The parent process is blocked in the main function and upon receiving the signal, handles it and returns from the call to wait with an error.

The child is just looping in the while handling SIGINT. When handled code returns where it was (probably blocked in sleep) and it continues to loop.

That code may illustrates what happens:

#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;
}

Be aware that calling printf in a signal handler is forbidden.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM