`std::chrono::system_clock::now().time_since_epoch()` 的时间从何而来?如果从多个线程访问,它会阻塞吗?

Where does the time from `std::chrono::system_clock::now().time_since_epoch()` come from and can it block if accessed from multiple threads?

std::chrono::system_clock::now().time_since_epoch()从何而来? 也就是说,它是与 crystal 振荡器(物理组件)的直接接口吗?

如果它是 crystal 振荡器,是每个内核一个还是所有内核一个?

如果所有内核都有一个振荡器,如果多个线程同时访问它(低延迟环境),它是否会阻塞线程?

如果每个核心有一个 crystal 个振荡器,它们是如何同步的?

C++ 标准不关心 system_clock::now() 是如何实现的。它只是指定

Returns a time_point object representing the current point in time.

典型的 C++ 标准库实现将依赖底层 OS 系统调用来获取实际的系统时钟值来构造 time_point 对象。

在硬件实现方面,您需要考虑硬件架构。但通常系统时钟的维护成本始终存在,无论有多少进程/线程正在读取它。并且系统时钟获取实现为一个轻量级例程,不会导致线程阻塞,不会成为多线程程序中的性能瓶颈。

此外,std::chrono::system_clock::now().time_since_epoch()是一个简单的观察者方法,它只returns在std::chrono::system_clock::now()返回的time_point对象中嵌入duration对象,它涉及仅 C++ 结构复制。

标准规定std::chrono::system_clock如下:

23.17.7.1 Class system_clock [time.clock.system]

Objects of class system_clock represent wall clock time from the system-wide realtime clock.

这有多重含义。首先,这个时钟的时间点可以通过 std::chrono::system_clock::to_time_tstd::chrono::system_clock::from_time_ttime_t 时间相互转换,暗示时钟代表某种物理时间。其次,时钟指定为 "system-wide",这意味着所有进程都应从该时钟中检索相同的 time_point 值。

实际上,这意味着此时钟最常通过调用 OS 检索某种时间的特定函数来实现,例如您在任务栏中看到的那样。

请注意,如果此时钟is_steady,则未指定。这意味着从这个时钟开始的 timepoints 不必总是前进。即使呼叫在物理时间上发生得较晚,您也可以获得更早的时间点。例如,如果用户通过某些 OS 设置调整时钟,就会发生这种情况。

更接近你描述的是std::chrono::steady_clock:

23.17.7.2 Class steady_clock [time.clock.steady]

Objects of class steady_clock represent clocks for which values of time_point never decrease as physical time advances and for which values of time_point advance at a steady rate relative to real time.

我们提到了两个要求。首先,时钟必须是单调的,所以时间永远不会"run backwards"。其次,时钟是稳定的,所以这个时钟的每个滴答声应该占用相同的物理时间。

使用某种硬件计数器(如循环计数器)来实现此时钟感觉很自然。但要小心:这个时钟不必是系统范围的。这是,这样一个值可以例如从当前正在执行的 CPU 中获取,即使可能存在其他具有不同计数器的 CPU。