讲师中心 微信公众号
AI工具推荐 视频效率加速

C++如何使用std::stop_token请求线程停止?(C++20协作取消)

老萱小哥_3014

老萱小哥_3014

发布时间:2026-02-20 08:19:02

|

185人浏览过

|

来源于php中文网

原创

std::stop_token必须由std::jthread自动传入线程函数首个参数,不可默认构造或捕获;应优先用stop_requested()轮询而非stop_callback;request_stop()仅设标志,需线程主动配合检查。

c++如何使用std::stop_token请求线程停止?(c++20协作取消)

std::stop_token 怎么拿到并传给线程函数?

你不能凭空构造 std::stop_token,它必须从 std::jthread 的 get_stop_token() 拿,或从另一个 std::stop_source 获取。直接在线程函数里声明 std::stop_token 参数但不传入,会导致编译失败或默认构造出“无效 token”(stop_possible() == false)。

正确做法是:用 std::jthread 启动线程,它会自动绑定一个 std::stop_source,并在启动时把对应的 std::stop_token 作为第一个参数传入线程函数。

  • std::jthread 是唯一能自动提供有效 std::stop_token 的标准线程类型;std::thread 不支持协作取消
  • 线程函数签名必须以 std::stop_token 为首个参数,否则 std::jthread 不会自动注入
  • 如果函数是 lambda,捕获 std::stop_token 无效——必须作为形参显式接收
void worker(std::stop_token st) {
    while (!st.stop_requested()) {
        // 做事...
        std::this_thread::sleep_for(100ms);
    }
}
std::jthread t{worker}; // ✅ 自动传入有效 token

stop_requested() 和 stop_callback 该选哪个轮询方式?

绝大多数场景下,只用 stop_requested() 就够了。它轻量、无副作用、可频繁调用。而 std::stop_callback 是“注册一次、触发一次”的机制,适合清理资源,不适合轮询。

  • stop_requested() 返回 bool,线程内可随时检查,适合循环条件或早期退出分支
  • std::stop_callback 构造时绑定一个 callable,仅在停止请求发出且 token 有效时执行一次;若线程已退出或 token 失效,回调不会运行
  • 误用 stop_callback 替代轮询会导致:停止请求被忽略(因为回调只触发一次,而线程可能还在循环中)
  • 回调对象的生命周期必须长于 std::stop_callback 实例,否则析构时可能访问悬垂引用
// ❌ 错误:以为回调能反复通知
std::stop_callback cb{st, []{ cleanup(); }}; // 只执行一次

// ✅ 正确:用 stop_requested() 控制循环
while (!st.stop_requested()) {
    do_work();
}
cleanup(); // 循环退出后再清理

std::jthread::request_stop() 为什么有时没反应?

常见原因是线程函数没在检查 stop_requested(),或者检查频率太低(比如阻塞在 std::condition_variable::wait() 中)。C++20 协作取消完全依赖线程主动配合,没有强制中断能力。

C++14
C++14

C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。

下载

立即学习“C++免费学习笔记(深入)”;

  • std::jthread::request_stop() 只是设置标志位,不挂起、不抢占、不抛异常
  • 如果线程卡在系统调用(如 read()、sleep())或无检查的长循环里,停止请求会一直等待
  • std::condition_variable::wait() 有重载支持 std::stop_token,应优先使用:cv.wait(lock, st, predicate)
  • 对 std::this_thread::sleep_for() 这类不可中断操作,需手动拆成带检查的小间隔循环
// ✅ 支持中断的等待
cv.wait(lock, st, []{ return ready; });

// ✅ 手动分段 sleep(避免长时间阻塞)
for (int i = 0; i < 10 && !st.stop_requested(); ++i) {
    std::this_thread::sleep_for(100ms);
}

和 std::thread + flag bool 相比,std::stop_token 有什么实际区别?

核心区别不是“能不能停”,而是“谁负责同步、是否线程安全、能否组合”。裸 flag 需要自己加 std::atomic 和内存序,而 std::stop_token 把这些封装好了,还支持嵌套取消源(比如子任务继承父任务的 token)。

  • 裸 std::atomic<bool></bool> 只能表达“单层开关”,无法区分“请求停止”和“已停止”,也难以安全传递给多个子线程
  • std::stop_token 与 std::stop_source 绑定,天然支持“一个 source 控制多个 token”,适合树状任务结构
  • std::stop_token::stop_requested() 内部已做最优内存序(通常是 memory_order_acquire),不用手写
  • 调试时,stop_token 可通过 stop_possible() 判断是否还有效,裸 flag 无法反映“token 是否已被 move 或销毁”

真正容易被忽略的是:一旦 std::jthread 对象析构,其绑定的 std::stop_source 会自动 request_stop —— 这是隐式行为,若线程函数没响应,就会变成“静默未终止”。

热门AI工具

更多
AionClaw
AionClaw Hot

AionClaw是一款面向办公、创作和编程任务的AI桌面智能体。

Loomy
Loomy Hot

一款AI工具,主要用于科大讯飞发布的桌面级 AI 助理,比 OpenClaw 更易用、更安全!,适合需要提升相关任务效率的用户。

小橡皮AI

一款AI工具,主要用于小橡皮一键去AI味,将机器味重的内容改得更有活人感,防止因为 AI 内容被平台打上 AI 标签,以及限流,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

墨刀AI
墨刀AI Hot

一款AI图像与设计工具,主要用于产品经理的专属智能体,适合需要提升相关任务效率的用户。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

Laper
Laper Hot

Laper是专为编剧、导演和制片人推出的 AI 原生剧本创作工具。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

UpDream
UpDream Hot

一款AI视频创作工具,主要用于哔哩哔哩推出的自研AI视频创作工具,适合需要提升相关任务效率的用户。

相关专题

更多
登录token无效
登录token无效

登录token无效解决方法:1、检查token的有效期限,如果token已经过期,需要重新获取一个新的token;2、检查token的签名,如果签名不正确,需要重新获取一个新的token;3、检查密钥的正确性,如果密钥不正确,需要重新获取一个新的token;4、使用HTTPS协议传输token,建议使用HTTPS协议进行传输 ;5、使用双因素认证,双因素认证可以提高账户的安全性。

14466

2023.09.14

登录token无效怎么办
登录token无效怎么办

登录token无效的解决办法有检查Token是否过期、检查Token是否正确、检查Token是否被篡改、检查Token是否与用户匹配、清除缓存或Cookie、检查网络连接和服务器状态、重新登录或请求新的Token、联系技术支持或开发人员等。本专题为大家提供token相关的文章、下载、课程内容,供大家免费下载体验。

1705

2023.09.14

token怎么获取
token怎么获取

获取token值的方法:1、小程序调用“wx.login()”获取 临时登录凭证code,并回传到开发者服务器;2、开发者服务器以code换取,用户唯一标识openid和会话密钥“session_key”。想了解更详细的内容,可以阅读本专题下面的文章。

3997

2023.12.21

token什么意思
token什么意思

token是一种用于表示用户权限、记录交易信息、支付虚拟货币的数字货币。可以用来在特定的网络上进行交易,用来购买或出售特定的虚拟货币,也可以用来支付特定的服务费用。想了解更多token什么意思的相关内容可以访问本专题下面的文章。

6181

2024.03.01

登录token无效
登录token无效

登录token无效解决方法:1、检查token的有效期限,如果token已经过期,需要重新获取一个新的token;2、检查token的签名,如果签名不正确,需要重新获取一个新的token;3、检查密钥的正确性,如果密钥不正确,需要重新获取一个新的token;4、使用HTTPS协议传输token,建议使用HTTPS协议进行传输 ;5、使用双因素认证,双因素认证可以提高账户的安全性。

14466

2023.09.14

登录token无效怎么办
登录token无效怎么办

登录token无效的解决办法有检查Token是否过期、检查Token是否正确、检查Token是否被篡改、检查Token是否与用户匹配、清除缓存或Cookie、检查网络连接和服务器状态、重新登录或请求新的Token、联系技术支持或开发人员等。本专题为大家提供token相关的文章、下载、课程内容,供大家免费下载体验。

1705

2023.09.14

token怎么获取
token怎么获取

获取token值的方法:1、小程序调用“wx.login()”获取 临时登录凭证code,并回传到开发者服务器;2、开发者服务器以code换取,用户唯一标识openid和会话密钥“session_key”。想了解更详细的内容,可以阅读本专题下面的文章。

3997

2023.12.21

token什么意思
token什么意思

token是一种用于表示用户权限、记录交易信息、支付虚拟货币的数字货币。可以用来在特定的网络上进行交易,用来购买或出售特定的虚拟货币,也可以用来支付特定的服务费用。想了解更多token什么意思的相关内容可以访问本专题下面的文章。

6181

2024.03.01

Vite 项目如何打包和部署
Vite 项目如何打包和部署

Vite项目打包部署专题汇集生产构建、产物预览、输出目录、资源路径、Nginx与GitHub Pages部署及常见白屏和路由404问题的已审核文章,帮助读者完成上线流程。

60

2026.10.28

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C++ Core Guidelines
C++ Core Guidelines

共0课时 | 0人学习

C++ Reference
C++ Reference

共0课时 | 0人学习

C++ 官方标准说明
C++ 官方标准说明

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn