我正在编写以下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
我的错误是什么?另外,我想问一下使用这样的程序可以得到的最高精度是多少?
非常感谢!
答案 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)
setitimer
和getitimer
不是用于分析的正确函数。它们与间隔定时器有关,它们是定时器到期时产生警报(信号更准确)的定时器。
实现目标的主要选项是clock
或clock_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