0

我试图通过查看数据的时间戳来查看我的数据是否是 120 秒(或 2 分钟)旧的,所以当我chrono在 C++ 中使用包时,我有以下代码:

uint64_t now = duration_cast<milliseconds>(steady_clock::now().time_since_epoch()).count();
// check for 2 minutes old data
bool is_old = (120 * 1000 < (now - data_holder->getTimestamp()));   

uint64_t value = now;
while (now < data_holder->getTimestamp() + 80 * 1000 
        && now < value + 80 * 1000) {
    std::this_thread::sleep_for(std::chrono::milliseconds(100));
    now = duration_cast<milliseconds>(steady_clock::now().time_since_epoch()).count();
}

在上面的代码data_holder->getTimestamp()中是 uint64_t,它以毫秒为单位返回时间戳。

现在当我打印出now变量值时,我看到了这个10011360,当我打印出data_holder->getTimestamp()值时1437520382241

2015-07-21 16:13:02,530 WARN 0x7f35312d1700 data_check - now value: 10011360 , data holder timestamp: 1437520382241

从上面的数据持有者时间戳来看,它看起来不是 120 秒的旧数据,所以我觉得我的代码有问题?因为如果我将该数据持有者时间戳转换为实际时间(使用纪元转换器),然后将其与如上所示的日志时间进行比较,它几乎是相同的。

所以我决定使用system_clock代替steady_clock并想出了下面我开始使用auto代替的代码uint64_t

解决方案 A:

auto now = system_clock::now();
auto dh_ts = system_clock::time_point{milliseconds{data_holder->getTimestamp()}};
bool is_old = (minutes{2} < (now - dh_ts));

早些时候,我使用now变量值uint64_t代替auto. 现在在上面的代码之后,我的原始代码中有类似的东西,因为now不是uint64_t,所以我在编译代码时遇到了编译错误。

uint64_t value = now;
while (now < data_holder->getTimestamp() + 80 * 1000 
        && now < value + 80 * 1000) {
    std::this_thread::sleep_for(std::chrono::milliseconds(100));
    now = duration_cast<milliseconds>(steady_clock::now().time_since_epoch()).count();
}

解决此问题的正确方法是什么?我无法更改data_holder->getTimestamp()数据类型,必须是uint64_t因为其他代码也在使用它。

这是错误:

error: cannot convert std::chrono::time_point<std::chrono::_V2::system_clock, std::chrono::duration<long int, std::ratio<1l, 1000000000l> > >â to âuint64_t {aka long unsigned int}â in initialization

更新:

Solution A如果下面的一切看起来都很好,我可以像这样使用而不是使用吗?

解决方案 B:

uint64_t now = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
bool is_old = (120 * 1000 < (now - data_holder->getTimestamp()));
4

2 回答 2

2

至少在我读到它的时候,这是一次睡 100 毫秒,然后检查它是否睡了 2 分钟。然后重复直到达到 2 分钟点。

在我看来,计算所需时间并在此之前睡眠更有意义:

struct foo { 
    time_point<system_clock> time_stamp;

    time_point<system_clock> get_timestamp() { return time_stamp; }
    foo() : time_stamp(system_clock::now()) {}
};

// ...    
foo f;

std::this_thread::sleep_until(f.get_timestamp() + 2m);

这确实使用(C++14 中的新功能)用户定义的文字来构造 2 分钟的持续时间。如果您确实需要支持较旧的 (C++11) 编译器,则需要minutes(2)改用。

至于标题问题,我会说:说不。将您的 time_points 存储为实际 time_points 比坚持将它们填充为整数,然后在您需要再次使用它们时将它们转回 time_points 要好得多。完全不明显的是,这完成了任何有用的事情来换取痛苦。

于 2015-07-23T01:30:54.683 回答
0

实际上,我建议更多地朝着解决方案 A 的方向前进,并将其余uint64_t时间转换为 time_points:chrono单位制非常有用。我将首先定义一个辅助函数以将uint64_t对象上的时间戳转换为 time_points:

using u64_millis = duration<uint64_t, milli>;
static time_point<system_clock, u64_millis> u64_to_time(uint64_t timestamp) {
    return time_point<system_clock, u64_millis>{u64_millis{timestamp}};
}

如果您的时代与 for 的时代不同system_clock,这将是修复它的地方。它可能也可以使用milliseconds而不是u64_millis,但是没有明确定义的表示类型,milliseconds并且按照上述方式进行操作可以确保类型正确匹配。

现在,您发布的代码如下所示:

auto now = system_clock::now();
bool is_old = now - u64_to_time(data_holder->getTimestamp()) > minutes{2};

auto value = now;
while (now - u64_to_time(data_holder->getTimestamp()) < seconds{80}
        && now - value < seconds{80}) {
    this_thread::sleep_for(milliseconds{100});
    now = system_clock::now();
}
于 2015-07-23T01:04:13.597 回答