首页 > 解决方案 > sys/time.h 定时器只运行一次

问题描述

我正在尝试实现一个计时器,该计时器在软件运行时连续计算一定的时间。我写了一个肮脏的代码来尝试 sys/time.h 是如何工作的。
我的理解是,如果我将 it_interval 结构设置为非零值,那么一旦完成对存储在 it_value 结构中的值的计数,计时器就应该再次开始计数。
但是,我的代码停止了。有人可以告诉我我的代码中缺少什么吗?另外,我正在使用Linux。

#include <sys/time.h>
#include <stdio.h>
#include <stdint.h>

int main(void) {
    struct itimerval timer1;

    timer1.it_interval.tv_sec = 5;
    timer1.it_interval.tv_usec = 0;
    timer1.it_value.tv_sec = 5;
    timer1.it_value.tv_usec = 0 ;
    setitimer(ITIMER_REAL, &timer1, NULL);
    printf( "init interval counter: %ld.%ld\n", timer1.it_interval.tv_sec, 
    timer1.it_interval.tv_usec);
    printf( "init value counter: %ld.%ld\n\n", timer1.it_value.tv_sec, 
    timer1.it_value.tv_usec );

    while(1) {
        for (int i = 0; i < 100000000000000; i++){
            getitimer(ITIMER_REAL, &timer1);
            printf( "end interval counter: %ld.%ld\n", 
            timer1.it_interval.tv_sec, timer1.it_interval.tv_usec);
            printf( "end value counter: %ld.%ld\n\n", 
            timer1.it_value.tv_sec, timer1.it_value.tv_usec );
        }
    }
    return 0;
}

我的输出(当然缩短了)是:
结束间隔计数器:5.0
结束值计数器:0.8821

结束间隔计数器:5.0闹钟

进程返回 142 (0x8E) 执行时间:5.033 s

预先感谢您的帮助!

标签: ctimetimer

解决方案


setitimer(ITIMER_REAL,...)导致SIGALRM在计时器到期时发送到调用进程。SIGALRM是一个通常致命的信号,其默认处置是终止进程。

如果你想防止你的进程被这个信号杀死,你需要以某种方式处理它。

基于您的代码的示例(每 100 毫秒从处理程序打印 EXPIRED):

#include <sys/time.h>
#include <stdio.h>
#include <stdint.h>
#include <signal.h>
#include <unistd.h>
void handler(int Sig)
{
    (void)Sig;
    char msg[]="EXPIRED\n";
    ssize_t nwr = write(1,msg,sizeof(msg)-1); (void)nwr;
}
int main(void) {
    struct itimerval timer1;
    struct sigaction sa;
    sa.sa_handler = handler;
    sa.sa_flags = 0;
    sigemptyset(&sa.sa_mask);
    sigaction(SIGALRM,&sa,0);

    timer1.it_interval.tv_sec = 0;
    timer1.it_interval.tv_usec = 100000;
    timer1.it_value.tv_sec = 0;
    timer1.it_value.tv_usec = 100000 ;
    setitimer(ITIMER_REAL, &timer1, NULL);
    printf( "init interval counter: %ld.%ld\n", timer1.it_interval.tv_sec, 
    timer1.it_interval.tv_usec);
    printf( "init value counter: %ld.%ld\n\n", timer1.it_value.tv_sec, 
    timer1.it_value.tv_usec );

    while(1) pause();
    return 0;
}

推荐阅读