GetTickCount64是Windows下获取系统启动以来毫秒级Tick的首选API,返回64位无符号整型,避免32位溢出,精度约10–16ms,需用ULONGLONG接收,不需额外链接库。

Windows下用GetTickCount64获取毫秒级Tick数
Windows提供GetTickCount64作为首选API,返回自系统启动以来的毫秒数,64位无符号整型,避免了GetTickCount的49.7天溢出问题。它精度约10–16ms(取决于系统定时器分辨率),不需额外链接库,直接包含<windows.h>即可调用。
常见错误是误用GetTickCount(返回DWORD,32位有符号),在运行超49.7天后会回绕为负值;还有人试图用timeGetTime,但它依赖winmm.lib且同样有32位溢出风险。
- 必须链接
kernel32.lib(默认已链接,一般无需显式指定) - 返回值类型是
ULONGLONG,别用int或long接收 - 若需更高精度(如微秒级),应改用
QueryPerformanceCounter+QueryPerformanceFrequency
Linux/macOS用clock_gettime替代gettimeofday
gettimeofday虽能获取微秒级时间,但它返回的是“墙上时间”(wall-clock time),受NTP校正、时钟调速等影响,不适合做相对间隔测量;而clock_gettime(CLOCK_MONOTONIC, ...)返回单调递增的系统运行时间,更接近Windows的Tick语义。
注意CLOCK_MONOTONIC从内核启动开始计时,不包括系统挂起时间;如果需要包含挂起时间,可用CLOCK_BOOTTIME(Linux 2.6.39+),但glibc版本太低时可能未定义。
立即学习“C++免费学习笔记(深入)”;
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
- 需定义
_GNU_SOURCE或_POSIX_C_SOURCE >= 199309L才能使用clock_gettime - 链接时通常无需额外选项,但某些嵌入式环境可能需加
-lrt - 返回单位是纳秒,除以1'000'000可转为毫秒(与Windows
GetTickCount64单位一致)
C++11跨平台方案:慎用std::chrono::steady_clock
std::chrono::steady_clock设计目标就是单调、不可逆、适合测量间隔,其now().time_since_epoch().count()在多数实现中底层映射到CLOCK_MONOTONIC(Linux)或QueryPerformanceCounter(Windows),比手写平台API更简洁。
但要注意:steady_clock的“起点”是实现定义的(比如可能是进程启动、系统启动,或任意偏移),所以它不能直接等价于Windows的“自启动毫秒数”——除非你只关心差值。若真需要绝对Tick数(例如日志对齐、调试时序),跨平台时就得按平台分别实现。
- 不要用
system_clock,它对应墙上时间,会被系统时钟调整干扰 - 不同标准库实现中
steady_clock::period可能不同(纳秒/微秒),务必用duration_cast转换 - Clang/libc++在较老macOS上曾将
steady_clock退化为mach_absolute_time,精度略低但仍是单调的
精度和用途混淆是最大陷阱
很多人想用“Tick数”做性能计时,却选了GetTickCount64或clock_gettime(CLOCK_REALTIME),结果发现两次调用差值忽大忽小——这是因为它们本质是系统调度器更新的“软Tick”,不是硬件级高精度计数器。
真正需要微秒甚至纳秒级测量时,QueryPerformanceCounter(Windows)和clock_gettime(CLOCK_MONOTONIC_RAW)(Linux)才是正确选择;而如果只是粗略判断“程序已运行多久”或“是否超时”,GetTickCount64或steady_clock完全够用。
另外,C++标准不保证steady_clock的epoch与系统启动时间对齐,所以即使数值看起来像毫秒数,也不能直接当作Windows Tick来用。

















