一个支持暂停和继续的 C++ 时间管理类
2026/5/8 18:34:20 网站建设 项目流程

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

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

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

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

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

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


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

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

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

于是就有了下面这个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本质上不是计时器,
而是一个时间状态管理器

如果你做的是:

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

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


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

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询