C++如何获取系统启动时间 _ GetTickCount与uptime方法【实战】
C++如何获取系统启动时间:GetTickCount与uptime方法实战

免费影视、动漫、音乐、游戏、小说资源长期稳定更新! 👉 点此立即查看 👈
在跨平台开发中,获取系统启动时间是个看似简单、实则暗藏玄机的任务。Windows下的GetTickCount64和Linux下的/proc/uptime,这两者提供的“启动时间”在语义上有着本质区别,直接互换使用,往往是线上监控告警误触发的罪魁祸首。
Windows用GetTickCount64获取开机后毫秒数(不含休眠),Linux用/proc/uptime读取实际运行总秒数(含休眠),二者语义不同不可互换;GetTickCount因32位溢出(约49.7天)已被淘汰。
Windows:为什么不用 GetTickCount 而必须用 GetTickCount64
先说说Windows平台。老牌的GetTickCount函数返回一个32位无符号整数,这意味着它在大约49.7天后就会溢出归零。对于需要长期稳定运行的服务或嵌入式设备来说,这无疑是个定时冲击波——系统明明没重启,程序却可能误判为刚刚启动。
所以,答案很明确:必须使用它的64位升级版——GetTickCount64。它返回ULONGLONG类型,理论溢出周期长达约584年,足以应对绝大多数场景。
- 链接与单位:函数位于
kernel32.lib中(MSVC编译器通常默认已链接)。其返回值单位是毫秒,除以1000.0即可转换为秒级浮点数。 - 关键语义:这里有个至关重要的细节:
GetTickCount64的值从系统启动开始累计,但不计入系统进入睡眠或休眠状态的时间。换句话说,如果机器休眠了两小时再唤醒,这个计时器的数值并不会增加那两小时。 - 示例代码:
ULONGLONG uptime_ms = GetTickCount64();
Linux:读 /proc/uptime 的正确姿势
转到Linux世界,获取启动时间的标准姿势是读取/proc/uptime这个虚拟文件。它比uptime命令更底层、更轻量,尤其适合嵌入式或需要高频采样的场景。
这个文件通常包含两个以空格分隔的浮点数:第一个字段是系统启动以来的实际运行总秒数(这个“实际”包含了系统休眠的时间);第二个字段则是总的空闲时间。
- 读取方法:用C++的
std::ifstream打开文件,直接读取第一个double值即可,简单高效。 - 权限与精度:普通用户就有读取权限,无需root。其精度对于秒级应用完全足够;如果追求纳秒级精度,则应考虑结合
clock_gettime(CLOCK_BOOTTIME, ...)。 - 示例代码:
std::ifstream f(“/proc/uptime”); double up_sec; f >> up_sec;
跨平台封装时最常踩的坑
到了封装跨平台接口这一步,才是真正考验理解深度的时候。最常见的错误,就是试图用一个宏或函数名统一两者,然后返回一个uint64_t类型的毫秒数。这忽略了最根本的语义差异:Windows不计休眠,Linux计入休眠。一旦机器进入休眠,两个平台返回的时间增量就会产生巨大分歧,直接导致依赖于此的监控、调度逻辑出错。
那么,正确的设计思路是什么?
- 明确接口语义:在设计上,最好明确区分“系统运行时间”和“系统启动时刻”这两个概念。对于运行时间,各自使用原生方法获取。若需要计算启动的绝对时刻,Windows推荐用
GetSystemTimeAsFileTime获取当前时间后反推,Linux则可用clock_gettime(CLOCK_BOOTTIME, ...)。 - 避开时间陷阱:千万不要用
time(NULL) - boot_time这种方式来估算运行时间。系统时间可能被NTP校准或手动修改,这样计算的结果毫无可靠性可言。 - 容器环境特例:在Docker等容器环境中,
/proc/uptime反映的是宿主机的运行时间,而非容器自身的。如果需要容器的启动时间,需要另辟蹊径,例如通过检查/proc/1/stat来获取容器内第一个进程的启动时间戳。
立即学习“C++免费学习笔记(深入)”;
说到底,真正的难点不在于调用哪个API或读取哪个文件,而在于精确理解“系统启动时间”在你当前的上下文里究竟指代什么:是内核加载完成的那一刻?是第一个用户进程启动的瞬间?还是上次从休眠中恢复的时刻?选错了语义基准,后续的所有计算和判断都将失之毫厘,谬以千里。
游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。
同类文章
Go 中结构体方法接收器类型错误导致的 nil 指针解引用问题解析
深入解析Go语言值接收器与指针接收器的核心差异:规避运行时崩溃的关键 在Go语言开发中,为结构体方法选择值接收器还是指针接收器,绝非随意的语法决策,而是直接影响程序行为与稳定性的核心设计。一个普遍存在的编码误区是:开发者试图在方法内部为结构体的指针类型字段赋值,却错误地使用了值接收器。这种操作实际上
Python如何解决多线程下的死锁问题_使用RLock与超时机制优化
Python多线程死锁:RLock的常见误解与高效解决方案 在Python多线程编程实践中,死锁是一个普遍且棘手的并发问题。许多开发者存在一个误区,认为使用threading RLock就能彻底规避死锁风险,这种认知可能导致严重的线上隐患。本文将深入剖析RLock的真实作用边界,并提供一系列经过实战
如何检查值是否不在数组中并生成对应的非工作日列表
如何检查值是否不在数组中并生成对应的非工作日列表 本文介绍在 PHP 中高效判断当前日期是否未出现在分组工作日数组中,并据此构建非工作日列表的完整实现方法,涵盖 array_column 与 in_array 的正确组合用法、避免重复逻辑、日期格式对齐及结构化输出。 在考勤或排班系统的开发中,我们常
如何搭建Python项目自动化打包流程_配置Setuptools与PyProject
PyProject toml:现代Python项目打包配置的核心指南 在Python的打包与分发领域,pyproject toml 文件已成为无可争议的现代标准配置方案。整个Python打包生态系统,包括主流的 setuptools 构建工具,都已全面转向并推荐使用此文件。如果你仍在直接编写和维护传
Flask中Celery任务如何获取数据库连接_Python应用上下文app_context传递技巧
Flask中Celery任务如何获取数据库连接:Python应用上下文app_context传递技巧 在Flask项目里集成Celery处理后台任务,一个经典的“坑”就是:任务函数里直接调用db session,结果迎面抛来一个RuntimeError: Working outside of app
- 日榜
- 周榜
- 月榜
1
2
3
4
5
6
7
8
9
10
1
2
3
4
5
6
7
8
9
10
相关攻略
2015-03-10 11:25
2015-03-10 11:05
2021-08-04 13:30
2015-03-10 11:22
2015-03-10 12:39
2022-05-16 18:57
2025-05-23 13:43
2025-05-23 14:01
热门教程
- 游戏攻略
- 安卓教程
- 苹果教程
- 电脑教程
热门话题

