未调用信号函数

Signal function not being called

我正在尝试向 child 进程发送来自 parent 的空白 (SIGUSR1) 信号。据我所知,我已经正确设置了信号。我觉得我搞砸了 Kill() 函数调用。我期待某种打印输出,但我什么也没得到。不是来自 child 内部,也不是来自信号函数本身。

代码:

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");
    }
}

子进程在父进程有机会向它发送信号之前退出。尝试在调用 signal.

后在子进程中添加 sleep(5)

你child在信号发送前退出:

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

child 可能会打印 +1,但随后会退出。与此同时,你的 parent 等待两秒钟以确保 child 真的死了,然后向它发送一个信号。它不存在!

修复:添加某种代码,使 child 挂起以接收信号。最简单的可能是 pause();,尽管 sleep() 超过 2 秒也可以。

你应该检查你的系统调用。例如:

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

您很快就厌倦了编写 4 行代码,因此您最终得到一个报告系统错误并退出的函数(使用 C11 _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? 这不是您的问题的一部分,但您应该了解这些问题。