如何使用单个信号处理程序解决这个多个 linux 计时器 [英] how to solve this multiple linux timer with single signal handler

查看:43
本文介绍了如何使用单个信号处理程序解决这个多个 linux 计时器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

/*处理程序检查存储在 sival_ptr 中的值是否与给定的 timerID 匹配多变的.sival_ptr 与我们在 makeTimer() 中设置的相同,虽然在这里它生活在不同的结构中.显然,它在通往该信号处理程序的途中从那里复制到了这里.关键是 timerID 是用来确定哪个计时器刚刚关闭的并决定下一步做什么 */

/*The handler checks that the value stored in sival_ptr matches a given timerID variable. The sival_ptr is the same as the one we set in makeTimer(), though here it lives in a different structure. Obviously, it got copied from there to here on the way to this signal handler. The point is that the timerID is what is used to determine which timer just went off and determine what to do next */

static void timerHandler( int sig, siginfo_t *si, void *uc )
{
    timer_t *tidp;

    tidp = si->si_value.sival_ptr;

    if ( *tidp == firstTimerID )

        TASK1(Task2ms_Raster);
   else if ( *tidp == secondTimerID )
       TASK2(Task10ms_Raster);
    else if ( *tidp == thirdTimerID )
        TASK3(Task100ms_Raster);
}

/*该函数需要一个指向 timer_t 变量的指针,该变量将被填充timer_create() 创建的定时器 ID.这个指针也保存在sival_ptr中在调用 timer_create() 之前的变量.在这个函数中注意我们始终使用 SIGRTMIN 信号,因此任何计时器到期都会导致此信号被抚养.我为该信号编写的信号处理程序是 timerHandler.*/

/* The function takes a pointer to a timer_t variable that will be filled with the timer ID created by timer_create(). This pointer is also saved in the sival_ptr variable right before calling timer_create(). In this function notice that we always use the SIGRTMIN signal, so expiration of any timer causes this signal to be raised. The signal handler I've written for that signal is timerHandler. */

 static int makeTimer( char *name, timer_t *timerID, int expireMS, int intervalMS )
{
     //sigset_t mask;
    struct sigevent         te;
    struct itimerspec       its;
    struct sigaction        sa;
    int                     sigNo = SIGRTMIN;

    /* Set up signal handler. */
    sa.sa_flags = SA_SIGINFO;
    sa.sa_sigaction = timerHandler;
    sigemptyset(&sa.sa_mask);
    if (sigaction(sigNo, &sa, NULL) == -1)
    {
        perror("sigaction");
    }

    /* Set and enable alarm */
    te.sigev_notify = SIGEV_SIGNAL;
    te.sigev_signo = sigNo;
    te.sigev_value.sival_ptr = timerID;
    timer_create(CLOCK_REALTIME, &te, timerID);

    its.it_interval.tv_sec = 0;
    its.it_interval.tv_nsec = intervalMS * 1000000;
    its.it_value.tv_sec = 0;
    its.it_value.tv_nsec = expireMS * 1000000;
    timer_settime(*timerID, 0, &its, NULL);


    return 1;
}

int main()
 {

     makeTimer("First Timer", &firstTimerID, 2, 2);   //2ms

   makeTimer("Second Timer", &secondTimerID, 10, 10);    //10ms
   makeTimer("Third Timer", &thirdTimerID, 100, 100);  //100ms


 }

我使用单个处理程序每​​ 2 毫秒、10 毫秒和 100 毫秒调用一次任务.我在单个信号处理程序中使用多个计时器.如何识别哪个计时器刚刚过去.在调试模式下:最后一个调试控制会话是: static void timerHandler( int sig, siginfo_t *si, void *uc ){ .谁能帮我解决这个问题?

I am using single handler to call the task for every 2ms, 10ms and 100ms. I am using multiple timers with single signal handler. How to identify which timer just went. In debug mode : the last debug control session is : static void timerHandler( int sig, siginfo_t *si, void *uc ){ . Could anyone help me how to solve this ?

推荐答案

只需每 2 毫秒使用一个计时器并增加一个计数器.每次点击都会有 2 毫秒事件,每 5 次点击也会有 10 毫秒事件,每 50 次点击也会有 100 毫秒事件.

Just use one timer every 2 msec and increment a counter. On every hit you have the 2 msec event, every 5th hit you also have the 10 msec event, and every 50th hit you also have the 100 msec event.

注意:一般的解决方案是让计时器每 1 毫秒命中一次,并有一个要比较的超时列表.它们不必都是彼此的倍数.

Note: the general solution is to have the timer hit every 1 msec and to have a list of timeouts to compare. They don't all have to be multiples of each other.

这篇关于如何使用单个信号处理程序解决这个多个 linux 计时器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆