使用clock_gettime()的正确方法是什么?

使用clock_gettime()的正确方法是什么?,c,time.h,C,Time.h,我在一个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,

我在一个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;
}
#包括
#包括
#包括
#包括
int main(int argc,字符**argv){
结构timespec开始、结束;
时钟获取时间(时钟实时和启动);
睡眠(1);
时钟获取时间(时钟实时和完成);
printf(“%f\n”)((double)(finish.tv\u nsec-start.tv\u nsec))/(double)100000);
返回0;
}

我不确定这是否是由于转换为
double
时的舍入错误造成的异常,或者我是否错误地使用了
clock\u gettime()
函数,但是我希望它输出1秒,而不是1.27秒。

在计算由返回的两个值之间的时间差时,需要考虑结构的
tv_sec
成员


tv\u nsec
是当前秒内的纳秒数。它的范围(理论上)在0到9999999之间。这允许在
tv\u sec
中存储整数秒,在
tv\u nsec
中存储小数秒。实际解决方案是另一个问题:请参阅。例如,在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;
}
这是在Mac上测试的;您可以看到最后三位数字总是零。在Linux虚拟机(Mac上的Ubuntu 18.04)中,我必须在代码中添加
\define\u POSIX\u C_SOURCE 200809L
(因为我用
-std=c11
编译;如果我用
-std=gnu11
,我就可以了),结果是:

$ ./cgt61
1.000589528
$

1纳秒是100000000秒。另外,如果从秒33.433开始,在秒34.42991停止,finish.tv_nsec-start.tv_nsec之间的差值为负值,这不是可靠的时间增量计算。通常,您需要使用整秒以及纳秒进行计算,尽管您通常可以侥幸逃脱。输出的数字是十分之一毫秒——这对于系统调用和调度的开销来说是合理的。但是:你忽略了时间规格的
tv\u sec
元素中记录的整整一秒的差异。
tv\u nsec
纳秒数与秒数之比也是如此吗?这就解释了为什么我除以10亿时这个数太小。
tv\u nsec
是当前秒内的纳秒数。它的范围(理论上)在0到9999999之间。这允许在
tv\u sec
中存储整数秒,在
tv\u nsec
中存储小数秒。实际分辨率是另一个问题:请参见
clock\u getres()
。例如,在Mac电脑上,分辨率是微秒,即使分辨率是以纳秒表示的。
$ ./cgt61
1.000589528
$