如何解决使用std :: chrono进行时间戳记-如何基于相对时间“过滤”数据? 以秒为单位获取时钟的周期和每秒滴答值获取时钟的时间点现在作为uint64值以对数据流进行时间戳记根据存储的uint64值获取时钟时间点
我想对我产生的数据流进行时间标记,为此我要使用 std :: chrono :: steady_clock 。
这些时间戳与数据一起存储(作为uint64值的数组吗?),以后我将需要再次处理这些时间戳。
现在,到目前为止我还没有使用过std :: chrono库,因此我确实需要一些有关该库的语法和最佳实践的帮助。
uint64_t timestamp = std::chrono::steady_clock::Now().time_since_epoch().count();
但我该怎么办:
上面的代码段将不胜感激。
我想结合以上三个基本内容来执行以下操作:具有一组(递增的)时间戳记值(如uint64),我希望将其截断,以使所有数据都比上次时间戳记“旧”减去X秒。
解决方法
让我们看看您可能在chrono的cppreference文档中使用的功能。
首先,您需要确定要使用哪个时钟。您建议使用steady_clock
,high_resolution_clock
和system_clock
。
high_resolution_clock
是依赖于实现的,所以除非我们确实需要它,否则我们将其丢弃。 steady_clock
可以保证是单调的,但是不能保证所获得的值的含义。是对事件进行排序或测量其间隔的理想选择,但您无法从中获得时间点。
另一方面,system_clock
的含义是UNIX时代,因此您可以从中获取时间值,但不能保证它是单调的。
要获取steady_clock
的时间段(一滴答的持续时间),您需要拥有period
成员:
auto period = std::chrono::steady_clock::period();
std::cout << "Clock period " << period.num << " / " << period.den << " seconds" << std::endl;
std::cout << "Clock period " << static_cast<double>(period.num) / period.den << " seconds" << std::endl;
假设您要使用steady_clock
值过滤最近几秒钟内发生的事件,则首先需要计算所需时间段内的滴答数,并将其从now
中减去。类似于:
std::chrono::system_clock::time_point now = std::chrono::system_clock::now();
std::time_t t_c = std::chrono::system_clock::to_time_t(now - std::chrono::seconds(10));
并使用t_c
作为截止点。
但是,不要依靠std::chrono::steady_clock::now().time_since_epoch().count();
来获得有意义的东西-仅仅是数字。 steady_clock
的时期通常是启动时间。如果需要时间,则应使用system_clock
(请注意,这不是单调的)。
C ++ 20a引入了更多的时钟,这些时钟可以转换为时间。
,由于我花了很长时间才从今天的各种来源中弄清楚,所以我将在此处发布我的解决方案作为自我解答。 (我希望对此发表评论,以防万一某些事情不正确或可以做得更好。)
以秒为单位获取时钟的周期和每秒滴答值
using namespace std::chrono;
auto period = system_clock::period();
double period_s = (double) period.num / period.den;
uint64 tps = period.den / period.num;
获取时钟的时间点(现在)作为uint64值以对数据流进行时间戳记
using namespace std::chrono;
system_clock::time_point tp_now = system_clock::now();
uint64 nowAsTicks = tp_now.time_since_epoch().count();
根据存储的uint64值获取时钟时间点
using namespace std::chrono;
uint64 givenTicks = 12345; // Whatever the value was
system_clock::time_point tp_recreated = system_clock::time_point{} + system_clock::duration(givenTicks);
uint64 recreatedTicks = tp_now.time_since_epoch().count();
Assert( givenTicks == recreatedTicks ); // has to be true now
最后一个(从uint64到timepoint)让我最困扰。所需的主要见解是:
-
(在Win10上) system_clock 使用100纳秒的时间分辨率。因此,不能直接将
std::chrono::nanoseconds
添加到其本地时间点。 (std::chrono:system_clock_time_point
) -
但是,由于刻度是100纳秒,因此也不能使用下一个较高的持续时间单位(微秒),因为它不能表示为整数值。
-
一个人可以使用 explicit 强制转换为微秒,但这会降低刻度的0.1us分辨率。
-
正确的方法是使用system_clock自己的持续时间,并使用存储的滴答值直接对其进行初始化。
在搜索中,我发现以下资源最有帮助:
-
Lecture of Howard Hinnant on YouTube -非常有用。我希望我从这里开始。
在time_point和duration和time_since_epoch 上的 -
cppreference.com
-
cplusplus.com 在steady clock和time_point
参考手册是通常看起来不错的地方:
https://en.cppreference.com/w/cpp/chrono
在这种情况下,您正在寻找:
https://en.cppreference.com/w/cpp/chrono/clock_time_conversion
因为实际上您使用的时钟是“历元” 1/1/70作为原点,而ms作为单位。 然后只需对持续时间使用算术即可完成所需的截止时间:
https://en.cppreference.com/w/cpp/chrono/duration
每个链接页面底部都有代码示例。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。