std::stop_callback是c++20中配合std::jthread和std::stop_token实现协作式取消的raii回调机制,构造时注册、析构时自动注销,适用于资源清理、状态通知等场景。

std::stop_callback 是什么,什么时候该用它
std::stop_callback 是 C++20 引入的用于配合 std::jthread 和 std::stop_token 实现协作式取消的工具。它不是“自动触发”的钩子,而是一个 RAII 类型:构造时注册回调,析构时自动注销。适用于需要在任务被请求停止时**做清理、释放资源、通知外部状态**等场景,比如关闭文件句柄、取消 pending 的异步操作、记录日志。
注意:它只在 std::stop_token 被 request_stop() 触发后、且回调尚未被销毁时执行;如果 token 早已停止,回调会立即同步执行(若仍在作用域内);如果 callback 对象已析构,则不会执行。
怎么构造和使用 std::stop_callback
必须传入一个 std::stop_token 和一个可调用对象(lambda、函数指针、functor)。回调函数不能抛异常(否则 terminate),参数列表必须为空(void())。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
-
std::stop_callback对象生命周期决定回调是否有效——离开作用域即注销,不会被重复调用 - 同一个
std::stop_token可绑定多个std::stop_callback,执行顺序是后注册先执行(栈式) - 回调执行时机是不确定的:可能在
request_stop()调用期间同步执行,也可能稍后由其他线程异步执行(取决于实现) - 示例:
std::jthread t([](std::stop_token st) { std::stop_callback cb(st, []{ std::cout
常见错误:为什么回调没执行
最常踩的坑是 std::stop_callback 对象生命周期太短,或绑定的 token 不可用。
- 把
std::stop_callback声明在 if 分支或循环体内,作用域结束就注销 → 回调永远不会被调用 - 误用普通
std::thread:它不提供std::stop_token,直接传std::stop_token{}或默认构造的 token → 回调永远不触发 - 在回调里访问已析构的对象(比如捕获了局部变量的 lambda,而该变量已在回调执行前离开作用域)→ UB
- 回调函数抛异常 → 程序直接终止,不会捕获
和 std::jthread::request_stop() 配合的关键点
std::jthread 在析构时自动调用 request_stop() 并 join,这是它比 std::thread 安全的核心。但要注意:
- 手动调用
t.request_stop()后,所有已注册的std::stop_callback(且未析构)会尽快执行,但不保证立刻返回 - 如果线程函数里没有检查
stop_requested(),仅靠std::stop_callback无法中断正在运行的 CPU 密集型循环——它只是“通知+清理”,不是抢占式中断 - 多个
std::stop_callback注册在同一 token 上时,不要依赖执行顺序——标准只保证“后注册先执行”,不保证与其他 callback 的绝对时序
真正容易被忽略的是:回调执行时,线程可能仍在运行,也可能已退出,甚至可能正在析构中。别在回调里做阻塞、锁全局资源或再次调用 request_stop() —— 这些都可能引发死锁或未定义行为。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










