必须用 std::chrono,clock() 返回 cpu 时间不反映真实流逝;推荐 steady_clock;重试间隔优先固定值,仅对外部服务才用指数退避。

超时判断用 std::chrono 还是 clock()?
必须用 std::chrono,clock() 返回的是 CPU 时间,不反映真实流逝,重试逻辑会严重失准。比如一段阻塞 I/O 占用大量 CPU 时间但实际只过几毫秒,clock() 会误判超时。
实操建议:
- 统一用
std::chrono::steady_clock(单调、不受系统时间调整影响) - 起始时间记为
auto start = std::chrono::steady_clock::now() - 每次检查用
std::chrono::duration_cast<:chrono::milliseconds>(std::chrono::steady_clock::now() - start).count()</:chrono::milliseconds> - 避免用
system_clock——系统时间被手动修改时会导致超时提前或延后
重试间隔该用固定值还是退避策略?
绝大多数场景下,固定间隔(如 100ms)足够;只有调用外部服务(如 HTTP、RPC)才需指数退避,否则可能触发对方限流或雪崩。
实操建议:
- 本地逻辑或轻量操作:直接
std::this_thread::sleep_for(std::chrono::milliseconds(100)) - 对接网络服务:用指数退避,第 n 次重试延迟为
min(1000, 100 * (1 ms(上限防失控) - 别在循环里用
sleep_for后再立刻检查超时——要先算剩余时间,再sleep_for剩余时间,否则可能多等一轮
怎么写一个可中断的重试循环?
硬等超时不够灵活,尤其在多线程或响应式场景中,需要支持外部信号提前终止。
实操建议:
- 传入一个
std::atomic<bool>& stop_flag</bool>或std::stop_token(C++20) - 每次循环开头检查
if (stop_flag.load()) break; - 把
sleep_for拆成小块(如每次最多睡 10ms),中间插入 stop 检查,避免卡死 - 不要用
std::condition_variable::wait_for替代 sleep —— 它依赖 mutex,引入锁开销且易出竞态
std::future::wait_for 能不能直接替代手写超时?
能,但仅适用于你已封装好异步任务的场景;如果底层是同步调用(比如一个阻塞的 connect() 或自定义函数),wait_for 不起作用——它只能等待 future 状态变更,不能中断正在执行的同步代码。
实操建议:
- 已有
std::async或std::packaged_task:用future.wait_for(timeout)最简洁 - 底层是同步函数(如
do_work()):必须自己控制超时 + 重试,无法靠 future 包装“自动中断” - 注意
wait_for返回std::future_status::timeout时,任务仍在后台运行——没做 cancel 机制的话,资源可能泄漏
真正难的不是写个循环加计时器,而是想清楚:超时是给用户看的响应承诺,还是保护自身资源的熔断开关。前者要平滑降级,后者得立刻切断。两者混用,重试逻辑就容易既不快也不稳。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











