c++ - std::chrono::system_time 的 Visual Studio 2017 CRT 实现使用什么时钟?

标签 c++ windows visual-c++

chrono 标题中的注释只是说

// wraps GetSystemTimePreciseAsFileTime/GetSystemTimeAsFileTime

但它实际使用的是什么(即我期望的精度是多少)?该实现调用 _Xtime_get_ticks,但该函数是不透明的。

最佳答案

CRT 在可用时调用 GetSystemTimePreciseAsFileTime,否则调用 GetSystemTimeAsFileTimeGetSystemTimePreciseAsFileTime 为您提供 highest possible level of precision (<1us) .

有时在运行时初始化期间,一个名为 initialize_pointers 的函数被调用,它基本上执行以下操作(反编译和简化):

HMODULE hModule = GetModuleHandleW(L"kernel32.dll");

__encodedKERNEL32Functions[0] = (void *)GetProcAddress(hModule, "FlsAlloc");
__encodedKERNEL32Functions[1] = (void *)GetProcAddress(hModule, "FlsFree");
__encodedKERNEL32Functions[2] = (void *)GetProcAddress(hModule, "FlsGetValue");
__encodedKERNEL32Functions[3] = (void *)GetProcAddress(hModule, "FlsSetValue");

...


__encodedKERNEL32Functions[24] = (void *)GetProcAddress(hModule, "GetSystemTimePreciseAsFileTime");

...

在装有 Windows 8 或更新版本的系统上,__encodedKERNEL32Functions[24] 将为非零值。

然后归结为:

std::chrono::system_clock::now()
-> _Xtime_get_ticks
   -> __crtGetSystemTimePreciseAsFileTime(FILETIME *)

void __crtGetSystemTimePreciseAsFileTime(FILETIME *lpSystemTimeAsFileTime)
{
    void (*f)(FILETIME *) = (void (*)(FILETIME *))__encodedKERNEL32Functions[24];
    if (f)                         // if GetSystemTimePreciseAsFileTime exists
        f(lpSystemTimeAsFileTime); // call it
    else
        GetSystemTimeAsFileTime(lpSystemTimeAsFileTime);
}

至少这是(大约)在 14.16.27024.1 版本的 msvcp140.dllmsvcp140d.dll 中的实现方式。

当然,所有这些都没有记录在案并且可能会发生变化。

如果您需要使用GetSystemTimePreciseAsFileTime,您应该write your own clock而不是依赖实现细节。

关于c++ - std::chrono::system_time 的 Visual Studio 2017 CRT 实现使用什么时钟?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54933940/

相关文章:

c++ - 一个重载的函数调用运算符可以有多少个操作数?

linux - Boxcryptor 和 CloudFogger 等加密服务如何工作?

c++ - 如何重载 << 运算符?

c++ - 什么是 isWindowsServer API for VS 2008 编译器的等价物

c++ - 为什么 C++ 模板不会导致多重定义错误?

c++ - 未处理的异常 - OpenCV - cvReleaseCapture 和 cvReleaseImage - C++

windows - 是否可以将两个调试器附加到一个进程?

c++ - move 构造函数可以是隐式的吗?

c++ - 如何处理clang中的全局构造函数警告?

Java NIO 和 Windows 磁盘访问