如何获取与系统时间无关的时间差(毫秒)?

3

我需要在Linux(Ubuntu 14)上计算毫秒级的时间差。

这个时间差需要独立于系统时间,因为应用程序在执行过程中可能会更改它(根据从GPS接收到的数据设置系统时间)。

我已经检查了clock函数,但它对我们来说不起作用,因为它返回程序消耗的处理器时间,而我们需要真实时间。

sysinfo(如此问题中所述)返回自启动以来的秒数,而我们需要毫秒。

并且从/proc/uptime中读取(如此问题中所述)根据我们的测试似乎很慢(考虑到我们想要毫秒级别,而且这个函数被重复调用)。

我们可以使用C++11,但我认为std::chrono也与系统时间有关(如果我错了,请纠正我)。

还有其他方法可以完成这个任务吗?


我们的性能测试(用于比较/ proc / uptime),100万次重复调用:

gettimeofday:

(不是我们需要的,因为它取决于系统时间)

#include <sys/time.h>

unsigned int GetMs(){
    unsigned int ret = 0;
    timeval ts;
    gettimeofday(&ts,0);
    static long long inici = 0;
    if (inici==0){
        inici = ts.tv_sec;
    }
    ts.tv_sec -= inici;
    ret = (ts.tv_sec*1000 + (ts.tv_usec/1000));
    return ret;
}

时钟:

(无效,返回应用程序使用的滴答数,而非实际时间)

#include <time.h>
unsigned int GetMs(){
    unsigned int ret = 0;
    clock_t t;
    t = clock();
    ret = t / 1000;
    return ret;
}

运行时间:

#include <fstream>
unsigned int GetMs(){
    unsigned int ret = 0;
    double uptime_seconds;
    if (std::ifstream("/proc/uptime", std::ios::in) >> uptime_seconds) {
        ret = (int) (1000 * uptime_seconds);
    }
}

结果:

  • gettimeofday:31 毫秒
  • clock:153 毫秒
  • uptime:6005 毫秒
2个回答

9
您需要的是 std::chrono::steady_clock

std::chrono::steady_clock 表示单调时钟。该时钟的时间点不会随着物理时间向前移动而减少。该时钟与墙上时钟时间无关(例如,它可以是自上次重启以来的时间),最适合用于测量时间间隔。

如果您需要支持 C++98/03 环境,您也可以使用 boost:steady_clock

感谢您的回答。它完美地运行,并且不依赖于系统时钟,这符合我的要求。然而,根据我的测试,我接受@zwol的答案,因为它更快。在我的嵌入式设备上,1000000次重复调用,std::chrono::steady_clock花费了3523毫秒,而使用CLOCK_MONOTONIC的clock_gettime花费了2184毫秒。 - Pau Guillamon
@PauGuillamon 没问题。很高兴能帮助你。 - NathanOliver

4
您想要的低级系统原语是使用CLOCK_MONOTONIC“clockid”的clock_gettime函数。

CLOCK_MONOTONIC:表示自某个未指定的起始点以来的单调时间,不能设置。该时钟不受系统时间中断跳跃的影响(例如,如果系统管理员手动更改时钟),但会受到adjtime(3)和NTP执行的增量调整的影响。

(几乎可以肯定,“受adjtime(3)和NTP执行的增量调整的影响”就是您想要的。)

此函数在<time.h>中声明,并且在当前版本的GNU libc中默认可访问。对于旧版本,您可能需要将_POSIX_C_SOURCE定义为大于或等于200809L的值,在包含任何系统头文件之前(不仅仅是在包含time.h之前),您还可能需要将程序链接到-lrt

clock_gettime返回一个struct timespec,它可以表示单个纳秒的差异;实际精度通常略低,但您应该能够指望毫秒级精度,特别是如果正在运行“调节”系统时钟的程序(例如ntpd)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接