【问题标题】:How to measure elapsed time without being affected by changes in system time如何在不受系统时间变化影响的情况下测量经过时间
【发布时间】:2020-07-23 12:16:33
【问题描述】:

我想以秒为单位测量经过的时间。使用std::chrono::steady_clock 我会这样做。但是它会受到系统时间变化的影响。

难道不是 stable_clock 应该不受系统时间变化的影响吗?

我该怎么做?

代码如下:

#include <iostream>
#include <chrono>
#include <time.h>

std::chrono::steady_clock::time_point t = std::chrono::steady_clock::now();

/* Change system time */
std::time_t tnow = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
tnow -= 20;
std::cout << "stime: " << stime(&tnow) << std::endl;
/********************************************************/

sleep(5);
std::chrono::steady_clock::time_point t2 = std::chrono::steady_clock::now();
std::cout << "ELAPSED: " << std::chrono::duration_cast<std::chrono::seconds>(t2-t).count() << std::endl;

这个结果:

stime: 0
ELAPSED: -15

我想得到的是:

ELAPSED: 5

编辑:

我添加了 C 标签,因为它似乎是一个内核(或板的 buildroot)错误。那么,如果没有chrono,我怎么能做到这一点呢?我的意思是,直截了当(无需观察系统时间变化)。

时空出现之前的人们是怎样生活的?

【问题讨论】:

  • 这是什么编译器?我记得在 Microsoft 编译器上遇到了有关 stable_clcok 的问题。不确定它们是否已修复。
  • @JasperKent gcc
  • 关于您的编辑,您可以在 time.h 中使用 clock() 函数来测量经过的 CPU 时钟时间。
  • 我删除了 C 标签,因为这仍然是一个 C++ 问题。
  • @unlut,至少在这个例子中它不起作用,因为时钟不计算 sleep()。

标签: c++ chrono


【解决方案1】:

您可以向您的供应商提交错误。

From the standard:

steady_­clock 类的对象表示时钟,其值为 time_­point 永远不会随着物理时间的推移而减少 time_­point 的值相对于实际值以稳定的速度前进 时间。也就是说,时钟可能无法调整。

如果您可以在系统上找到可靠的单调时间来源,您可以轻松地将该来源包装在自定义 chrono::clock 中,然后仍然使用类型安全的计时系统。例如:

#include <chrono>

struct MyClock
{
    using duration                  = std::chrono::nanoseconds;
    using rep                       = duration::rep;
    using period                    = duration::period;
    using time_point                = std::chrono::time_point<MyClock>;
    static constexpr bool is_steady = true;

    static time_point now() noexcept
    {
        using namespace std::chrono;
        timespec ts;
        clock_gettime(CLOCK_MONOTONIC, &ts);
        return time_point{seconds{ts.tv_sec} + nanoseconds{ts.tv_nsec}};
    }
};

现在你可以这样说:

MyClock::time_point t = MyClock::now();
// ...
MyClock::time_point t2 = MyClock::now();
std::cout << "ELAPSED: " << std::chrono::duration_cast<std::chrono::seconds>(t2-t).count() << std::endl;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-04-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多