news 2026/6/15 17:18:12

一个支持暂停和继续的 C++ 时间管理类

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
一个支持暂停和继续的 C++ 时间管理类

前段时间在项目里碰到一个挺常见、但又特别容易写烂的需求:
统计时间。

听起来很简单,但一旦加上这几个条件,事情立刻变复杂:

  • 有一个总时间
  • 总时间由多个分段组成
  • 每个分段过程中可以暂停、恢复,而且可能不止一次
  • 暂停期间不能算有效时间

如果你随手用定时器或者不断累加,很快就会发现:
时间开始不对劲了。

要么多算了暂停时间,要么暂停几次之后就彻底乱套。

后来我索性停下来,重新想了一下:
时间这东西,真的有必要一直“加”吗?


换个思路:能算出来的,就别累加

最后我用的方案其实很简单:

  • 所有时间都用时间戳
  • 只在关键节点结算
  • 其余时候全部“现算”

于是就有了下面这个TimeManager


先上代码(核心就这些)

先写一个获取当前秒时间戳的小工具,用的是 C++ 自带的std::chrono

#include<chrono>staticuint64_tgetNowSeconds(){returnstd::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch()).count();}

然后是整个时间管理类:

classTimeManager{public:TimeManager():totalTime(0),segmentStartTime(0),segmentPauseTotal(0),totalPauseTotal(0),pauseStartTime(0),isPaused(false){}voidstartSegment(){segmentStartTime=getNowSeconds();segmentPauseTotal=0;isPaused=false;pauseStartTime=0;}voidpause(){if(isPaused||segmentStartTime==0)return;isPaused=true;pauseStartTime=getNowSeconds();}voidresume(){if(!isPaused||pauseStartTime==0)return;uint64_tnow=getNowSeconds();uint64_tpauseDuration=now-pauseStartTime;segmentPauseTotal+=pauseDuration;totalPauseTotal+=pauseDuration;isPaused=false;pauseStartTime=0;}voidstopSegment(){if(segmentStartTime==0)return;totalTime+=getSegmentTime();segmentStartTime=0;segmentPauseTotal=0;isPaused=false;pauseStartTime=0;}uint64_tgetSegmentTime()const{if(segmentStartTime==0)return0;uint64_tendTime=isPaused?pauseStartTime:getNowSeconds();returnendTime-segmentStartTime-segmentPauseTotal;}uint64_tgetTotalTime()const{returntotalTime+getSegmentTime();}private:uint64_ttotalTime;uint64_tsegmentStartTime;uint64_tsegmentPauseTotal;uint64_ttotalPauseTotal;uint64_tpauseStartTime;boolisPaused;};

代码不长,但逻辑我挺满意的。


这个类到底在干什么?

一句话概括就是:

总时间 = 已结束分段的时间 + 当前分段实时算出来的时间

这里有几个我刻意分开的概念。


1️⃣ 总时间是“已经记账的时间”

uint64_ttotalTime;

这个值只在一个地方改:
stopSegment()

也就是说,只有当我明确“这个分段结束了”,
它的有效时间才会被加到总时间里。

中途暂停、恢复、怎么折腾,都不碰它。


2️⃣ 分段时间永远不累加,全部现算

分段有效时间的公式其实很直白:

当前时间 - 分段开始时间 - 分段暂停时间

对应的代码就是:

uint64_tendTime=isPaused?pauseStartTime:getNowSeconds();returnendTime-segmentStartTime-segmentPauseTotal;

有一个细节我当时特意处理了:
如果正在暂停,时间直接冻结。

所以暂停多久,分段时间就真的一秒都不涨。


3️⃣ 暂停时间只在恢复那一刻结算

我见过不少代码,是在 pause 的时候就开始各种计算,
最后状态一多就完全兜不住。

我这里的逻辑很简单:

  • pause:只记一个时间点
  • resume:统一算这次暂停了多久
uint64_tpauseDuration=now-pauseStartTime;segmentPauseTotal+=pauseDuration;

这样不管你暂停多少次,都不会乱。


实际用起来是什么感觉?

比如这样一段流程:

TimeManager tm;tm.startSegment();// 干活// 10 秒tm.pause();// 停一下// 5 秒tm.resume();// 接着干// 8 秒tm.stopSegment();// 收工

最后得到的结果是:

  • 有效时间:18 秒
  • 暂停时间:5 秒
  • 总时间只加了 18 秒

暂停没有“偷”走任何有效时间。


写完之后的一个感受

时间统计这东西,最怕的不是代码写得少,而是状态太多。

后来我发现,只要记住一句话,问题就好解决很多:

能用时间戳算出来的,就别用变量去维护。

这个TimeManager本质上不是计时器,
而是一个时间状态管理器

如果你做的是:

  • 任务耗时统计
  • 工单 / 流程时间分析
  • 设备运行时间管理

这种思路基本都能直接套。


如果你对那些功能更感兴趣,也可以留言告诉我。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/15 16:40:26

看完就会:继续教育专用的降AI率工具,千笔AI VS 知文AI

在AI技术快速发展的今天&#xff0c;越来越多的学生和研究者开始借助AI工具辅助论文写作&#xff0c;提升效率、优化内容。然而&#xff0c;随着学术审查标准的不断提高&#xff0c;AI生成内容的痕迹逐渐被识别&#xff0c;AI率超标成为影响论文通过的重要隐患。面对查重系统对…

作者头像 李华
网站建设 2026/6/15 13:06:49

centos 7.9 ISO下载链接

最近在一台DELL台式机上安装rocky linux 9.5和rocky linux 8.10,都出现了错误。 而采用centos 7.9没有问题。 我是用DVD安装的&#xff0c;但是安装完成之后做KVM的环境还需要ISO。 下面是ISO的链接&#xff1a; https://vault.centos.org/7.9.2009/isos/x86_64/

作者头像 李华
网站建设 2026/6/15 14:02:39

git 常用操作

1. 首先判断项目结构 情况1&#xff1a;单一仓库&#xff0c;多模块&#xff08;Monorepo&#xff09; project/ ├── app/ # 主模块 ├── library1/ # 子模块 ├── library2/ # 子模块 └── build.gradle # 统一构建操作&#xff1a;在根目录操作…

作者头像 李华
网站建设 2026/6/15 13:43:51

孩子近视度数一路狂飙?看看是不是这些原因

‍  孩子近视后&#xff0c;家长最揪心的莫过于看着度数一次次复查都往上涨&#xff0c;明明已经叮嘱了少看电子屏幕&#xff0c;也简单做了护眼措施&#xff0c;却还是挡不住度数“狂飙”。很多家长把原因归结为户外活动少、用眼环境差等常见问题&#xff0c;却忽略了那些藏…

作者头像 李华
网站建设 2026/6/15 11:53:30

2026 年 Google Ads 广告投放风险点:为什么需要指纹浏览器?

随着 2026 年的到来&#xff0c;Google Ads 的风控已经从传统的 IP 检查升级为更高级的行为分析系统。普通的代理 IP 或单纯的浏览器操作&#xff0c;已经难以完全规避风险。账户封号、广告限流、审核延迟等问题&#xff0c;越来越频繁地发生在广告投放团队中。本文将从 Google…

作者头像 李华