在C

时间:2016-02-27 05:15:06

标签: c time setitimer

我正在编写以下C代码,以便花时间使用getitimer和setitimer执行简单的操作。

#include <sys/time.h>
#include <stdlib.h>
#include <stdio.h>
#include <limits.h>
#include <string.h>

#define INTERVAL 1        /* number of milliseconds to go off */

int main() {
    double sum = 0;
    struct itimerval initial, updated;

    initial.it_value.tv_sec     = INTERVAL;
    initial.it_value.tv_usec    = 999999;
    initial.it_interval = initial.it_value;
    memcpy(&(initial.it_interval), &(initial.it_value), sizeof( initial.it_value )); 
    printf("%ld\n", initial.it_value.tv_usec);

    if (setitimer(ITIMER_VIRTUAL, &initial, NULL) == -1) {
        perror("error calling setitimer()");
        exit(1);
    }

    for (unsigned int i; i < 100; i++) 
        sum += 1./i;

    if (getitimer(ITIMER_REAL, &updated) == -1) {
        perror("error calling getitimer()");
        exit(1);
    }

    printf("Time started = %ld\n; Time ended = %ld\n: Time taken = %ld\n",
           initial.it_value.tv_usec, updated.it_value.tv_usec,
           initial.it_value.tv_usec - updated.it_value.tv_usec);
    return 0;
}

我已编译:

$ gcc -o timer -std=c99 -Wall -pedantic getitimer.c -lrt -03

但是,我的答案总是999999(我已经提高并减少了100):

 ./timer 
999999
Time started = 999999
; Time endd = 0
: Time taken = 999999

我的错误是什么?另外,我想问一下使用这样的程序可以得到的最高精度是多少?

非常感谢!

3 个答案:

答案 0 :(得分:1)

我看到的主要是除法运算使用整数除法。所以:

initial.it_value.tv_sec     = INTERVAL/1000000;

在tv.sec中放置0

initial.it_value.tv_usec    = (INTERVAL/1000000) * 1000000;

在tv_usec中放置0

initial.it_interval = initial.it_value;

通常,在分配多字段结构时,请使用memcpy()而不是直接分配。 (直接赋值将用于初始化,但不适用于赋值。)

因此,发布的代码将'interval'设置为0

当然,结果值为0

这是setitimer()和getitimer()

的手册页中的关键语句

“定时器从it_value递减到零,生成信号,然后重置为        it_interval。设置为零的计时器(it_value为零或计时器到期且it_interval为零)停止。“

建议:以下编辑

initial.it_value.tv_set = INTERVAL;
initial.it_value.tv_usec = 0;

memcpy( &(initial.it_interval), &(initial.it_value), sizeof( initial.it_value ) );

...

答案 1 :(得分:0)

setitimergetitimer不是用于分析的正确函数。它们与间隔定时器有关,它们是定时器到期时产生警报(信号更准确)的定时器。

实现目标的主要选项是clockclock_gettime API。

答案 2 :(得分:0)

最新代码的主要问题是对getitimer()的调用是引用与调用setitime()不同的计时器

但是,以下代码使其易于使用

#include <sys/time.h>
#include <stdlib.h>
#include <stdio.h>
//#include <limits.h>
//#include <string.h>

// do not place comments on same line as #define statement
// always surround numeric values with parens to avoid 'text replacement' errors
// wrong comment:  number of milliseconds to go off

// number of seconds in interval
#define INTERVAL (1)

// number of usec in interval
#define MICRO_INTERVAL (999999)

int main() {
    //double sum = 0;
    struct itimerval initial;
    struct itimerval updated;

    initial.it_value.tv_sec     = INTERVAL;
    initial.it_value.tv_usec    = MICRO_INTERVAL;
    initial.it_interval.tv_sec  = INTERVAL;
    initial.it_interval.tv_usec = MICRO_INTERVAL;

    // remove this line: initial.it_interval = initial.it_value;
    // remove this line: memcpy(&(initial.it_interval), &(initial.it_value), sizeof( initial.it_value ));
    //printf("%ld\n", initial.it_value.tv_usec);

    printf( "Time value: %ld.%ld\n", initial.it_value.tv_sec, initial.it_value.tv_usec );
    printf( "Time interval: %ld.%ld\n", initial.it_interval.tv_sec, initial.it_interval.tv_usec );

    if (setitimer(ITIMER_VIRTUAL, &initial, &updated) == -1)
    {
        perror("error calling setitimer()");
        exit(1);
    }

    //for (unsigned int i=0; i < 10; i++)  // must initialize the 'i' variable
    //    sum += 1./i;

    // the 'which' parameter should be 'ITIMER_VIRTUAL'
    //     as that is what was started in the call to setitimer()
    //if (getitimer(ITIMER_REAL, &updated) == -1)
    //{
    //    perror("error calling getitimer()");
    //    exit(1);
    //}

    if (setitimer(ITIMER_VIRTUAL, &initial, &updated) == -1)
    {
        perror("error calling setitimer()");
        exit(1);
    }

    printf( "end interval counter: %ld.%ld\n", updated.it_interval.tv_sec, updated.it_interval.tv_usec );
    printf( "end value counter: %ld.%ld\n", updated.it_value.tv_sec, updated.it_value.tv_usec );

    //printf("Time started = %ld\n; Time ended = %ld\n: Time taken = %ld\n",
    //       initial.it_value.tv_usec, updated.it_value.tv_usec,
    //       initial.it_value.tv_usec - updated.it_value.tv_usec);
    return 0;
}

// accuracy is +/-1 microsecond, not millisecond

即使在对setitimer()的两次调用之间没有任何操作,结果输出是:

Time value: 1.999999
Time interval: 1.999999
end interval counter: 1.999999
end value counter: 2.3999