You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在std::chrono中对时长做减法并保证结果非负?

C++ chrono 实现非负剩余时长的方案

问题场景与现有代码

你当前的代码用于计算下次执行的剩余延迟时间,但存在潜在问题:当已耗时duration超过目标延迟时长时,减法结果会是负数,不符合剩余时间的业务逻辑(剩余时间不能为负)。现有代码如下:

auto start = std::chrono::steady_clock::now();
...
auto duration = std::chrono::steady_clock::now() - start;
return std::chrono::duration_cast<std::chrono::milliseconds>(
      std::chrono::milliseconds(getDelayBeforeNextExecution()) - duration);

解决方案:显式保证结果非负

必须显式与chrono::zero比较并返回零,因为C++的chrono::duration类型本身支持正负值(用来表示时间的先后方向),但在剩余延迟的场景下,负数没有实际意义,甚至可能导致后续等待逻辑出错。

你可以用两种方式实现:

方式一:条件判断

auto start = std::chrono::steady_clock::now();
...
auto duration = std::chrono::steady_clock::now() - start;
// 先统一转换为目标毫秒类型,避免类型不匹配
auto target_delay = std::chrono::milliseconds(getDelayBeforeNextExecution());
auto remaining = target_delay - duration;

// 确保剩余时间非负
if (remaining < std::chrono::milliseconds::zero()) {
    return std::chrono::milliseconds::zero();
}
return std::chrono::duration_cast<std::chrono::milliseconds>(remaining);

方式二:使用std::max简化代码

利用std::max直接取计算结果和零的较大值,代码更简洁:

auto start = std::chrono::steady_clock::now();
...
auto duration = std::chrono::steady_clock::now() - start;
auto target_delay = std::chrono::milliseconds(getDelayBeforeNextExecution());

return std::max(
    std::chrono::milliseconds::zero(),
    std::chrono::duration_cast<std::chrono::milliseconds>(target_delay - duration)
);

为什么要这么做?

当已耗时超过目标延迟时,剩余逻辑应该立即执行(即延迟0毫秒),而不是返回负数。如果直接返回负数,传给std::this_thread::sleep_for这类等待函数时,会触发未定义行为,导致程序异常或逻辑错误。

内容的提问来源于stack exchange,提问作者gruszczy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 17:02:13