信号功能未被调用

时间:2015-10-14 22:21:51

标签: c signals parent-child kill sigkill

我试图从父进程发送一个空白(SIGUSR1)信号。据我所知,我已正确设置信号。我觉得我搞乱了Kill()函数调用。我期待某种打印输出,但我什么都没得到。不是来自孩子内部,也不是来自信号功能本身。

代码:

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

2 个答案:

答案 0 :(得分:3)

子进程在父进程有机会向其发送信号之前退出。在致电sleep(5)后,请尝试在子流程中添加signal

答案 1 :(得分:2)

您的孩子在发送信号之前退出:

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

孩子可能会打印+1,但随后会退出。同时,你的父母等了两秒钟,以确保孩子真的死了,然后给它发信号。它不存在!

要修复:添加某种代码,让孩子闲逛以接收信号。最简单的可能是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?这不是您问题的一部分,但您应该了解这些问题。