拨开荷叶行,寻梦已然成。仙女莲花里,翩翩白鹭情。
IMG-LOGO
主页 文章列表 为什么chrono::system_clock回传微秒而clock_gettime回传纳秒

为什么chrono::system_clock回传微秒而clock_gettime回传纳秒

白鹭 - 2022-01-24 2150 0 0

std::chrono::system_clock::time_since_epoch().count() 以微秒为单位给出结果。

我想要以纳秒为单位的当前时间。但是我不能使用 high_resolution_clock 因为在我的系统上它是 stable_clock (单调时钟)的别名。

我知道我的系统具有纳秒能力,因为如果我使用 clock_gettime(CLOCK_REALTIME, &ts) 我得到正确的纳秒分辨率纪元时间。

如何告诉 std::chrono 使用纳秒分辨率?我想避免使用clock_gettime 并坚持使用cpp 包装器。

uj5u.com热心网友回复:

这听起来很适合撰写您自己的自定义时钟。这比听起来容易得多:

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

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

    static time_point now()
    {
        timespec ts;
        if (clock_gettime(CLOCK_REALTIME, &ts))
            throw 1;
        using sec = std::chrono::seconds;
        return time_point{sec{ts.tv_sec} duration{ts.tv_sec}};
    }
};

只要有你的now()电话clock_gettimeCLOCK_REALTIME然后chrono::time_pointnanoseconds分辨率打包退货

警告,我刚刚在 macOS 上尝试过这个,并now()连续呼叫了两次。它每次打印出相同的纳秒数。并且无法在纳秒内执行呼叫。所以我得到了纳秒精度,但不是纳秒精度。

如果您想my_clock参与 C 20std::chrono::clock_cast设施(正如 Nicol Bolas 在下面的评论中所建议的那样),请将这两个静态成员函式添加到my_clock

template<typename Duration>
static
std::chrono::time_point<std::chrono::system_clock, Duration>
to_sys(const std::chrono::time_point<my_clock, Duration>& tp)
{
    return std::chrono::time_point<std::chrono::system_clock, Duration>
        {tp.time_since_epoch()};
}

template<typename Duration>
static
std::chrono::time_point<my_clock, Duration>
from_sys(const std::chrono::time_point<std::chrono::system_clock, Duration>& tp)
{
    return std::chrono::time_point<my_clock, Duration>{tp.time_since_epoch()};
}

现在你可以这样说:

cout << clock_cast<system_clock>(my_clock::now()) << '\n';

您还可以clock_cast往返于参与该设施的所有其他 C 20 和自定义时钟clock_cast

uj5u.com热心网友回复:

你是?clock_gettime要求回传在纳秒的时间,不管你是什么访问时钟。这并不意味着CLOCK_REALTIME实际上提供了这种分辨率。它可能在内部只有微秒分辨率,并通过乘以 1000 来表示纳秒。

相比之下,计时时钟实际分辨率由实作指定。它不是 UI 的强制部分;它可能因系统时钟而异因此,如果特定实作的单位system_clock::period为微秒,那么这就是该实作愿意声称提供的所有分辨率。

也许实作可以提供更多的解决方案,但如果可以,它可能会这样说。因此,如果没有,那么这意味着实作声称提供更多解决方案并不舒服。

但是,如果您觉得这clock_gettime确实提供了更好的分辨率(而不是简单地提供更多数字),则可以使用它。在 C 20 中,system_clock明确是 UNIX 时间。因此,如果您有时间以纳秒为单位,您可以将其转换为time_point<system_clock, nanoseconds>

namespace chrono = std::chrono;

...

using nano_sys = chrono::time_point<chrono::system_clock, chrono::nanoseconds>;

auto sys_tp_ns = nano_sys(chrono::nanoseconds(time_in_nanoseconds));

uj5u.com热心网友回复:

首先,请注意,在 GCC libstc 上,std::chrono 只是围绕 clock_gettime() 的语法糖的薄包装。你在这里谈论同样的事情。std::chrono 使用clock_gettime()。

    system_clock::time_point
    system_clock::now() noexcept
    {
      timespec tp;
      clock_gettime(CLOCK_REALTIME, &tp);
      return time_point(duration(chrono::seconds(tp.tv_sec)
                                   chrono::nanoseconds(tp.tv_nsec)));
    }

来源:https : //code.woboq.org/gcc/libstdc -v3/src/c 11/chrono.cc.html

(以上代码已清理)

所以精度就在那里,你只需要在纳秒内检索它

uint64_t utc_now_nanos() {
    std::chrono::steady_clock::time_point tp = std::chrono::steady_clock::now();
    return std::chrono::time_point_cast<std::chrono::nanoseconds>(tp).time_since_epoch().count();
}
标签:

0 评论

发表评论

您的电子邮件地址不会被公开。 必填的字段已做标记 *