C++ 实现倒计时并在结束时触发回调

陌强吖_4435

陌强吖_4435

2026-08-06

727人浏览

原创

用std::chrono+std::thread可实现轻量倒计时,需用steady_clock避免system_clock跳变,通过atomic标志控制线程生命周期,回调用shared_ptr管理对象存活,禁用sleep_for阻塞主线程,精度受限于系统调度(windows约15ms,linux约1–2ms)。

c++ 实现倒计时并在结束时触发回调

std::chrono + std::thread 实现精确倒计时

标准库没有内置倒计时类,但靠 std::chronostd::thread 能写出轻量、可控的实现。关键不是“等多久”,而是“怎么避免阻塞主线程又不丢精度”。

常见错误是直接用 std::this_thread::sleep_for 在主线程里等——这会让整个程序卡住;或者用 std::async 但没处理好生命周期,回调执行时对象已析构。

  • 倒计时单位统一用 std::chrono::milliseconds,避免浮点误差累积
  • 启动后立即返回,不阻塞调用方;回调通过 std::function<void></void> 传入,支持 lambda 或成员函数绑定
  • 必须在析构时主动中断线程(比如设置一个 std::atomic<bool></bool> 退出标志),否则可能 crash

如何安全绑定类成员函数作为回调

直接传 this 给线程容易悬空——倒计时还没走完,对象已经 delete 了。这不是语法问题,是生命周期管理失误。

正确做法是让倒计时对象持有对目标对象的 std::shared_ptr(如果目标本身是 shared),或要求用户显式传入一个有效的 std::shared_ptr。不推荐裸指针或 weak_ptr 做回调参数——weak_ptr::lock() 失败时你得决定是否静默跳过回调。

  • 示例:构造时接受 std::shared_ptr<myclass> self</myclass>,并在回调中先 if (auto ptr = self.lock()) { ptr->onTimeout(); }
  • 若回调只是无状态函数(如日志打印),直接传 std::function<void> f</void> 即可,无需智能指针
  • 注意:lambda 捕获 this 默认是值捕获,会复制指针,但不会延长对象寿命——这点极易忽略

为什么不用 std::async(std::launch::async)

看起来简洁:std::async 自动管理线程,但它的默认行为会在析构时阻塞等待完成——这意味着如果你创建倒计时后立刻离开作用域,程序会卡在析构上,直到倒计时结束。

C++ 算法竞赛自动化测试数据生成与校验框架
C++ 算法竞赛自动化测试数据生成与校验框架

根据原题生成新题面、验证器及完整测试数据,自动套用 testlib 模板,用于用户要求生成测试数据时。

下载

更糟的是,你无法提前取消它。C++20 前没有原生取消机制,std::async 返回的 std::future 不提供 cancel() 接口。一旦启动,只能等完或程序终止。

  • 除非你明确调用 .wait_for(0s).valid() 并放弃 future,否则风险很高
  • 真正需要异步且可取消,建议封装一层带原子标志的 std::thread,而不是依赖 std::async
  • 某些编译器(如 MSVC)对 std::async 的线程复用策略不透明,调试时难以定位超时偏差来源

精度和平台差异要注意什么

std::this_thread::sleep_for 的实际休眠时间可能略长于请求值,这是 OS 调度限制导致的,Windows 通常比 Linux 误差大(默认 15ms 左右),Linux 一般在 1–2ms 内。

如果你需要亚毫秒级响应(比如音视频同步),不要依赖 sleep + 回调,改用高精度定时器(如 Windows 的 timeSetEvent 或 Linux 的 timerfd_create),但这就超出标准 C++ 范畴了。

  • 普通 UI 或网络超时场景,std::chrono::steady_clock + sleep_for 完全够用
  • 测试时别用 system_clock——它可能被系统时间修改影响,导致倒计时跳变
  • 频繁创建/销毁倒计时对象?考虑对象池复用线程,避免反复创建线程开销

最常被忽略的不是怎么写,而是谁负责保证回调里访问的数据还活着。哪怕代码编译通过、跑起来一时没问题,只要对象生命周期没对齐,早晚 core dump。

C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

c++时间戳 c++ c++编程

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
c++和c语言的区别有哪些
c++和c语言的区别有哪些

c++和c语言的区别:1、面向对象编程(OOP)支持不同;2、新增特性不同;3、标准库不同;4、编译方式不同;5、命名空间不同等等。想了解更多c++的相关内容,可以阅读本专题下面的文章。

2024.03.14

2068

9

c++和python学习顺序推荐
c++和python学习顺序推荐

一般建议先学习C++,再学习Python,因为这样可以逐步从较为底层的编程语言向更高级的语言过渡。想了解更多python的相关内容,可以阅读本专题下面的文章。

2024.03.14

939

6

python和c++学习性价比分析
python和c++学习性价比分析

Python易于学习,广泛应用于Web开发、数据科学和人工智能等领域,但性能较低。C语言性能高,适用于对性能要求较高的场景,如游戏开发和系统编程,但学习曲线陡峭,错误处理复杂。想了解更多python的相关内容,可以阅读本专题下面的文章。

2024.03.14

367

5

c语言和c++一样吗
c语言和c++一样吗

c语言和c++是两种不同的编程语言,虽然有相似之处,但存在显著差异。c语言专注于过程式编程和系统级开发,以简洁、高效著称。c++作为c语言的超集,引入了面向对象编程,增强了代码组织和管理能力,但学习曲线也更陡峭。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.03.14

307

5

c语言和c++先学哪个好
c语言和c++先学哪个好

初学者选择学习c语言还是c++语言,需要根据个人学习目标、背景以及编程兴趣和预期应用方向来决定。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.03.14

346

5

c语言和c++的区别和联系
c语言和c++的区别和联系

c语言和c++是计算机科学领域应用广泛的编程语言。虽然它们有着相似的基础,但它们在语言类型、语法功能和内存管理方面存在着显著差异。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.03.14

560

5

c++软件中文更改教程
c++软件中文更改教程

对于 ide,可通过打开设置,找到语言设置,选择中文,并保存更改。对于非 ide 应用程序,可查找设置或选项,选择语言设置,更改为中文,并保存更改。想了解更多c++的相关内容,可以阅读本专题下面的文章。

2024.03.21

1389

9

python和java和c++学习性价比分析
python和java和c++学习性价比分析

Python以其易学性、丰富的库和活跃的社区而著称,适合数据科学、人工智能和Web开发。Java以其跨平台性、企业级应用开发和Android应用开发而闻名。C++以其底层控制能力、高效性能和游戏开发而著称。选择哪种语言取决于个人兴趣、职业方向和特定需求。想了解更多python和java和c++的相关内容,可以阅读本专题下面的文章。

2024.03.22

1177

7

c++和c语言学习顺序推荐
c++和c语言学习顺序推荐

对于初学者,建议先学习C语言,掌握编程基础后再转入C++,便于理解面向对象编程概念。有编程经验者可直接学习C++,快速接触高级编程技术。想了解更多c++和c语言的相关内容,可以阅读本专题下面的文章。

2024.03.25

1305

9

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Valgrind Quick Start Guide
Valgrind Quick Start Guide

共0课时 | 0人学习

CLion CMake 快速入门教程
CLion CMake 快速入门教程

共0课时 | 0人学习