1

我需要能够同时启动多个计时器,并明确知道计时器是否已停止或仍在运行。

#define RESEND_TIMEOUT  5

void timerCreate();
void timer_start(timer_t * timer, uint32 timeout);
bool timer_complete(timer_t * timer);

int main() {
    timer_t resend_timer = timerCreate();

    timer_start(&resend_timer, RESEND_TIMEOUT);
    while(1) {

    if (timer_complete(&resend_timer))
        break;
    }
}

void timer_start(timer_t * timer, uint32_t timeout)
{
    printf("timer starting\n");
    struct itimerspec it_val;
    it_val.it_value.tv_sec = timeout;
    it_val.it_value.tv_nsec = 0;

    // timer expires once
    it_val.it_interval.tv_sec = 0;
    it_val.it_interval.tv_nsec = 0;

    if (timer_settime(*timer, 0, &it_val, NULL) == -1) {
    errExit("Could not set timeout");
    }
}

// return true if timer ended
bool timer_complete(timer_t * timer)
{
    if(timer_getoverrun(*timer) == 0)
        return false;
    else
        return true;
}

我从不跳出循环。为什么我不能得到定时器的溢出(它总是返回0,这意味着定时器还没有过期)?然而,当我添加一个信号处理程序时,我知道计时器到期了。

我想在 timer_complete 函数中尝试 timer_gettime(timer_t timerid, struct itimerspec *curr_value) 以查看剩余时间是否为 0,但是如何在没有全局变量的情况下传递 curr_value 参数?

最后但并非最不重要的一点是,在使用 timer_settime 武装计时器时,我尝试使用 TIMER_ABSTIME 标志。从 int timer_settime(timer_t timerid, int flags, const struct itimerspec *new_value, struct itimerspec * old_value) 的手册页:

默认情况下,new_value->it_value 中指定的初始到期时间是相对于调用时计时器时钟上的当前时间来解释的。这可以通过在标志中指定 TIMER_ABSTIME 来修改,在这种情况下 new_value->it_value 被解释为在计时器时钟上测量的绝对值;即当时钟值达到new_value->it_value 指定的值时,定时器将超时。如果指定的绝对时间已经过去,则计时器立即到期,并且将正确设置溢出计数(请参阅 timer_getoverrun(2))。

4

1 回答 1

4

我从不跳出循环。为什么我不能得到定时器的溢出(它总是返回0,这意味着定时器还没有过期)?

不,这意味着你没有超支。

即使您指定实时信号,操作系统也不会将计时器信号排队。Overun 告诉您如果木夹头没有夹住信号,会有多少信号排队。

所以考虑你设置一个定时器,让它每秒响一次。但是由于某种原因,您没有处理信号。假设您将其阻止了 5 秒钟。溢出计数将是 4 - 您将/正在处理的信号和您错过的 4。

在您的情况下,您设置了一个一次性计时器以在“超时”秒后关闭。信号被传递。将不再有信号,因此溢出始终为 0,因为它应该是。

于 2013-11-06T22:06:44.047 回答