了解 gettimeofday 的输出

Understanding the output of gettimeofday

我想了解 gettimeofday() 系统调用的精度。这是我的程序:

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

int main(int argc, char *argv[])
{
    struct timeval t;
    int prev = 0;
    for (int i = 0; i < atoi(argv[1]); i++)
    {
        gettimeofday(&t, NULL);
        printf("secs: %ld, nmicro_secs: %d, delta: %d\n", t.tv_sec, t.tv_usec, t.tv_usec - prev);
        prev = t.tv_usec;   
        sleep(1);
    }   

    return 0;
    
}

如果我 运行 这个程序 (./a.out 10) 的输出是,

secs: 1643494972, nmicro_secs: 485698, delta: 485698
secs: 1643494973, nmicro_secs: 490785, delta: 5087
secs: 1643494974, nmicro_secs: 491121, delta: 336
secs: 1643494975, nmicro_secs: 494810, delta: 3689
secs: 1643494976, nmicro_secs: 500034, delta: 5224
secs: 1643494977, nmicro_secs: 501143, delta: 1109
secs: 1643494978, nmicro_secs: 506397, delta: 5254
secs: 1643494979, nmicro_secs: 509905, delta: 3508
secs: 1643494980, nmicro_secs: 510637, delta: 732
secs: 1643494981, nmicro_secs: 513451, delta: 2814

秒列似乎与 1 秒的睡眠相协调。有人可以解释一下微秒列中的值是怎么回事吗?看起来从睡眠到睡眠的跳跃约为 1 毫秒。

您仅使用 .tv_usec 字段计算两个连续调用之间的差异。换句话说,您正在丢弃 .tv_sec 字段,因此如果第一次测量产生 .tv_sec=1, .tv_usec=500000 (意味着自纪元以来 1.5s)而第二个测量产生 .tv_sec=2, .tv_usec=500000 (意味着自纪元以来 2.5s) ) 你的 delta 正好是 0,这是错误的。

您必须考虑整个值:t.tv_sec * 1000000 + t.tv_usec。只有这样,您才能计算出有意义的差异。请注意,您需要一个大于 int 的类型来保存此值。 uintmax_t 之类的东西应该足够了。或者,在注释中,两个不同的struct timeval如果你想计算没有中间类型的差异。

I am trying to understand the precision of the gettimeofday() system call

无论如何,none 你正在做的事情会告诉你gettimeofday精度,这是另一回事。在两个系统调用之间休眠将使您的进程在 not-so-deterministic 时间内处于非活动状态。