我在C程序中尝试了此功能,但它一直在打印错误的时间。这是我目前的代码:
#include <stdio.h>
#include <unistd.h>
#include <time.h>
#include <sys/resource.h>
int main( int argc, char **argv ){
struct timespec start, finish;
clock_gettime( CLOCK_REALTIME, &start );
sleep( 1 );
clock_gettime( CLOCK_REALTIME, &finish );
printf( "%f\n", ((double) (finish.tv_nsec - start.tv_nsec))/((double) 100000) );
return 0;
}
我不确定这是否是转换为double
时舍入错误引起的异常,还是我使用了clock_gettime()
函数不正确,但是我希望它能输出1秒,然后而是输出1.27秒。
答案 0 :(得分:1)
在计算clock_gettime()
返回的两个值之间的时间差时,需要考虑结构的tv_sec
成员。
tv_nsec
是当前秒内的纳秒数。理论上,它的范围是0到999,999,999。这允许将整数的整数秒存储在tv_sec
中,并将一秒的一部分存储在tv_nsec
中。实际分辨率是另一个问题:请参见clock_getres()
。例如,在Mac上,分辨率以微秒为单位,即使以纳秒表示。
考虑使用如下代码:
#include <stdio.h>
#include <time.h>
#include <unistd.h>
enum { NS_PER_SECOND = 1000000000 };
void sub_timespec(struct timespec t1, struct timespec t2, struct timespec *td)
{
td->tv_nsec = t2.tv_nsec - t1.tv_nsec;
td->tv_sec = t2.tv_sec - t1.tv_sec;
if (td->tv_sec > 0 && td->tv_nsec < 0)
{
td->tv_nsec += NS_PER_SECOND;
td->tv_sec--;
}
else if (td->tv_sec < 0 && td->tv_nsec > 0)
{
td->tv_nsec -= NS_PER_SECOND;
td->tv_sec++;
}
}
int main(void)
{
struct timespec start, finish, delta;
clock_gettime(CLOCK_REALTIME, &start);
sleep(1);
clock_gettime(CLOCK_REALTIME, &finish);
sub_timespec(start, finish, &delta);
printf("%d.%.9ld\n", (int)delta.tv_sec, delta.tv_nsec);
return 0;
}
运行时(为cgt61
),我得到的结果如下:
$ cgt61
1.004930000
$ cgt61
1.004625000
$ cgt61
1.003023000
$ cgt61
1.003343000
$
这已在Mac上进行了测试;您会看到最后三位数字始终为零。在Linux VM(在Mac上为Ubuntu 18.04)上,我必须在代码中添加#define _POSIX_C_SOURCE 200809L
(因为我使用-std=c11
进行了编译;如果使用-std=gnu11
,我会没事的) ,输出为:
$ ./cgt61
1.000589528
$