在其处理程序中捕获信号的最佳方法

时间:2014-11-20 21:02:06

标签: c++ c unix signals handler

我想在手柄中捕捉到信号。所以我为信号定义了自定义处理程序。使用结构,我也设置了SA_NODEFER,以允许其处理程序中的接收信号。但我不知道检查这个的最佳方法是什么。首先,我分叉子进程并在其中设置信号处理程序。然后我从父进程发送信号,但我不知道如何显示它,例如使用printf。我应该在hanlder中做些什么来捕获信号。 我将不胜感激任何帮助。感谢。

编辑

我需要在其处理程序中捕获信号。例如,我已经创建了这样的处理函数

void signal12_handler(int sig) { 
    printf("Signal has been received\n");
   // I need to do here some long time operations 
}

之后我从父进程发送信号,并在收到第一个信号后开始在处理程序中执行长时间操作,但不等待执行此操作的结束我发送相同的信号进行处理,我需要得到通知对这个。

我不知道这样做的正确方法是什么。

编辑2

int main()
{
    pid_t pid;
    printf("Starting...\n");
    pid = fork();
    if (pid == -1 )
    {
        printf("error\n");
        return 1;   
    }
    if (pid == 0)
    {

        printf("Child creation...\n");
        memset (&sig_12, '\0', sizeof(sig_12));
        sig_12.sa_handler = &signal12_handler;
        sig_12.sa_flags = SA_NODEFER;
     if (sigaction(SIGUSR2, &sig_12, NULL ) < 0) {
        perror ("sigaction");
    return 1;
    }

        while(true) {};

        printf("Child end ...\n");
    }
    else
    {
            printf("i`m parеnt, id=%d\n",getpid());
            printf("send SIGNAL 12\n");
            if (kill(pid,12)<0){printf("ERROR!\n");} 
            sleep(1);
            if (kill(pid,12)<0){printf("ERROR!\n");} 
            sleep(1);
            if (kill(pid,12)<0){printf("ERROR!\n");} 


    }


}

所以处理程序应该花费的时间比在我的情况下从父节点发送信号的时间间隔应该大于2秒(每秒2次睡眠)。

1 个答案:

答案 0 :(得分:0)

根据我们在评论中的讨论,我认为我对你的问题有可能的解释。

您正在使用SA_NODEFER标志来建立可重入信号处理程序。当然,当处理程序只执行打印并且实际上比重入计时器更快时,一切都很顺利。

但是当你开始在处理程序中进行实际工作时,重入不能很好地工作。

那是因为实际上只有少数 reentrant 库函数(线程安全,which is a different thing)。在大多数平台上,printf()malloc()本身(最有可能参与您的长期任务)are not reentrant

这意味着一旦你开始了长时间运行的任务,第二个可重入信号会中断第一个处理程序,再次运行它并直接通过非重入printf()调用。因此,即使在第二次长时间运行之前,程序的行为也会变得不确定。

可重入信号处理程序很棘手,可能对您的问题来说太低级了。如果您想要并行,请考虑多处理和/或多线程。