gettimeofday 是 Linux/macOS 下获取毫秒时间的最直接方案,需正确换算 tv_sec×1000 + tv_usec/1000 避免溢出;Windows 用 GetTickCount64;time()+clock() 仅作极端 fallback;std::time(nullptr) 不含毫秒信息,不可伪造。

用 gettimeofday 获取毫秒(Linux/macOS)
在没有 chrono 的旧项目或嵌入式受限环境里,gettimeofday 是最直接的替代方案,它返回带微秒精度的 struct timeval,换算成毫秒只需除以 1000。
常见错误是忽略 tv_usec 的范围(0–999999),直接 tv_sec * 1000 + tv_usec 会溢出;正确做法是先转毫秒再累加:
struct timeval tv; gettimeofday(&tv, nullptr); long long ms = tv.tv_sec * 1000LL + tv.tv_usec / 1000;
-
gettimeofday已被 POSIX 标记为废弃(但仍在 Linux/macOS 广泛支持) - 返回的是 wall-clock 时间,受系统时钟调整影响(如 NTP 跳变)
- 不能用于高精度间隔测量(比如性能计时),仅适合打点、日志时间戳等场景
Windows 下用 GetTickCount64 替代
Windows 没有 gettimeofday,但 GetTickCount64 返回自系统启动以来的毫秒数,64 位避免了 GetTickCount 的 49.7 天回绕问题。
注意它不反映真实挂钟时间,只适合计算相对间隔或粗略时间戳:
立即学习“C++免费学习笔记(深入)”;
auto ms = GetTickCount64(); // 直接就是毫秒值,无需换算
- 精度通常为 10–16ms(取决于硬件和电源策略),不是严格意义上的“毫秒级”
- 系统休眠期间该值不递增,所以不适合需要连续时间流的场景
- 必须链接
kernel32.lib,且最低支持 Windows Vista(XP 不支持GetTickCount64)
跨平台 fallback:组合 time() 和 clock()
如果连 gettimeofday 和 GetTickCount64 都不可用(例如某些裸机或极简 libc 环境),只能退而求其次:用 time() 获取秒级基准,再用 clock() 估算毫秒偏移。
但 clock() 返回的是 CPU 时间(非 wall-clock),且其分辨率极低(常为 10–15ms),误差大、不可靠:
time_t base = time(nullptr);
clock_t start = clock();
// ... 等待或运算 ...
double elapsed_ms = difftime(time(nullptr), base) * 1000.0 +
(double)(clock() - start) * 1000.0 / CLOCKS_PER_SEC;-
CLOCKS_PER_SEC在多数系统上是 1000000,但标准只要求 ≥ 1,实际值需运行时查 -
clock()可能只统计当前线程 CPU 时间,在多线程或空闲等待时完全失准 - 这种组合仅适用于对精度无要求、且无法引入任何系统 API 的极端情况
为什么坚决不推荐 std::time(nullptr) 单独用
std::time(nullptr) 只返回秒级整数,直接乘以 1000 得到的仍是秒粒度的“毫秒”,比如 1717023456000 这种值看起来像毫秒,但后三位恒为 000 —— 它根本没携带毫秒信息。
有人试图用循环等待来“凑”毫秒,比如:
while (time(nullptr) == t) { /* busy wait */ }- 这既浪费 CPU,又无法保证每次循环正好 1ms
- 在调度延迟、中断屏蔽或虚拟化环境下,误差可达几十毫秒
- 本质上不是“获取毫秒”,而是用不可控方式伪造毫秒
真要跨平台且不用 chrono,就老老实实按平台选 gettimeofday 或 GetTickCount64;别试图用 time() “假装”有毫秒精度。


















