timer_create()无法捕获处理函数中的信号

时间:2016-07-08 10:07:22

标签: c linux signals handler

在这里我尝试实现一个定时器说0-10secs和每个2secs的间隔,所以我需要每2秒生成一个中断@(总共5次)说完2secs。我一直在使用printf()交叉检查handler()函数。但是我无法达到预期的效果。如果有人意识到这一点,请让我联系。

提前致谢。

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
#include <time.h>
#define SIGTIMER                                (SIGRTMAX)
       #define errExit(msg)    do { perror(msg); exit(EXIT_FAILURE); \
                               } while (0)



        void handler(int sig, siginfo_t *si, void *uc)
       {
                      printf("Caught signal %d\n", sig);

       }

       int
       main(int argc, char *argv[])
       {
           timer_t timerid;
           struct sigevent sev;
           struct itimerspec its;
           struct itimerspec oitval;

           struct sigaction sa;

           /* Establish handler for timer signal */

           printf("Establishing handler for signal %d\n", SIGTIMER);
           sa.sa_flags = SA_SIGINFO;
           sa.sa_sigaction = handler;
           sigemptyset(&sa.sa_mask);
           if (sigaction(SIGTIMER, &sa, NULL) == -1)
               errExit("sigaction");

           /* Create the timer */

           sev.sigev_notify = SIGEV_SIGNAL;
           sev.sigev_signo = SIGTIMER;
           sev.sigev_value.sival_ptr = &timerid;
           if (timer_create(CLOCK_REALTIME, &sev, &timerid) == 0)
           {
           printf("timer ID is 0x%lx\n", (long) timerid);

           /* Start the timer */

           its.it_value.tv_sec = 10;
           its.it_value.tv_nsec =0;
           its.it_interval.tv_sec =   2;
           its.it_interval.tv_nsec =  0;

           if (timer_settime(timerid, 0, &its, &oitval) == -1)
                errExit("timer_settime");
           }
           else
           {
              errExit("timer_create");
           }

           return 0;
       }

1 个答案:

答案 0 :(得分:0)

首先,您应该正确设置超时:

       /* Start the timer */

       its.it_value.tv_sec     = 2;
       its.it_value.tv_nsec    = 0;
       its.it_interval.tv_sec  = 2;
       its.it_interval.tv_nsec = 0;

it_value是首次触发前的持续时间,it_interval是所有后续触发之间的时间。见here。然后,你不应该从main()返回,因为它会导致进程退出并且你无法观察计时器滴答声。你需要以某种方式阻止执行,例如

while(1) sleep(INT_MAX);

每次勾选sleep()后返回时errno设置为EINTR所以我们应该将其包装到循环中以允许计时器继续进行。稍后您可以决定何时离开此循环并退出。

P.S。使用信号处理程序中的printf()不是一个好主意。你应该非常认真地对待你在那里做的事情。最好只写一些全局变量并立即返回。并且可以在sleep()之后立即测试该var,以便了解您是否应该再次入睡或返回。