如果我有一个time_point
用于任意时钟(比如high_resolution_clock::time_point
),有没有办法将其转换为time_point
另一个任意时钟(比如system_clock::time_point
)?
我知道如果存在这种能力,就必须有限制,因为并非所有时钟都是稳定的,但有没有任何功能可以帮助规范中的这种转换?
答案 0 :(得分:16)
除非你知道两个时钟的时代之间的精确持续时间差异,否则无法准确地做到这一点。除非high_resolution_clock
为system_clock
,否则您不会对is_same<high_resolution_clock, system_clock>{}
和true
了解这一点。
话虽这么说,你可以编写一个近似正确的翻译,它就像T.C.在他的评论中所说的那样。实际上,libc ++在condition_variable::wait_for
:
https://github.com/llvm-mirror/libcxx/blob/master/include/__mutex_base#L385-L386
对不同时钟的now
的调用尽可能紧密地联系在一起,并且希望线程不会在这两个 的调用之间被抢先一步长。它是我所知道的最好的方法,并且规范在其中有摆动空间以允许这些类型的恶作剧。例如。允许有些东西醒来有点晚,但不是很早。
对于libc ++,底层操作系统只知道如何等待system_clock::time_point
,但规范说你必须等待steady_clock
(有充分理由)。所以你尽你所能。
这是一个关于这个想法的HelloWorld草图:
#include <chrono>
#include <iostream>
std::chrono::system_clock::time_point
to_system(std::chrono::steady_clock::time_point tp)
{
using namespace std::chrono;
auto sys_now = system_clock::now();
auto sdy_now = steady_clock::now();
return time_point_cast<system_clock::duration>(tp - sdy_now + sys_now);
}
std::chrono::steady_clock::time_point
to_steady(std::chrono::system_clock::time_point tp)
{
using namespace std::chrono;
auto sdy_now = steady_clock::now();
auto sys_now = system_clock::now();
return tp - sys_now + sdy_now;
}
int
main()
{
using namespace std::chrono;
auto now = system_clock::now();
std::cout << now.time_since_epoch().count() << '\n';
auto converted_now = to_system(to_steady(now));
std::cout << converted_now.time_since_epoch().count() << '\n';
}
对我来说,在-O3使用Apple clang / libc ++这个输出:
1454985476610067
1454985476610073
表示组合转换的误差为6微秒。
<强>更新强>
我已经在上述某个转换中随意颠倒了对now()
的调用顺序,以便一次转换以一个顺序调用它们,另一个转换以相反的顺序调用它们。此应该对任何一个转换的准确性没有影响。但是,当我在此HelloWorld中转换两种方式时,应该有统计消除,这有助于减少往返转换错误。