c - SIGINT 信号后进程终止

标签 c linux signals posix

我不明白这里发生了什么,我有一个父进程处理 SIGINT 信号,然后创建一个子进程。当我按 Ctrl+C 时,我期望两个进程都会打印“SIGINT returned”,然后继续,但事实证明,父进程在收到 SIGINT 后死亡,但 child 还在。我无法理解这一点。

#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,但父进程死亡,而子进程继续......

最佳答案

父进程在主函数中被阻塞,在接收到信号后,处理该信号并从对 wait 的调用中返回,并出现错误。

子进程只是在处理 SIGINT 的 while 中循环。当处理的代码返回到原来的位置时(可能在 sleep 中被阻塞)并且它继续循环。

该代码可以说明发生的情况:

#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

关于c - SIGINT 信号后进程终止,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52804701/

相关文章:

c - 在不知道维度的情况下在 C 中创建指向多维数组的指针

c - 分配内存后不执行代码

c++ - 替换为 cpp 中基于 getch 的代码块

python - 如何从 python 程序发送信号?

c++ - 是否有 C++ 标准库包装器或 pthread_sigmask 的替代品?

c++ - [文字游戏]Quiddler Solver Algorithm

python - 诅咒中的多个文本框

linux - 当有两个 gpu 时,如何设置 Torch 只使用一个 gpu?

java - 以编程方式触发完整的堆栈转储?

将文件中的数字字符串转换为 C 中的 int 数组