当前位置: 首页 > news >正文

C++20多线程新特性:更安全高效的并发编程

C++20引入的std::jthreadstd::stop_token通过自动生命周期管理内建的协作式取消机制,显著提升了多线程编程的安全性与便捷性,是对传统std::thread手动管理与粗放终止方式的重要革新。

🔄 1. 自动化的生命周期管理

std::jthread的核心优势在于其遵循**RAII(Resource Acquisition Is Initialization)**原则,能够自动管理线程的生命周期。

  • 传统 std::thread的困境:使用std::thread时,开发者必须在对象析构前手动选择调用join()(等待线程结束)或detach()(分离线程,让其后台运行)。如果忘记调用,程序会直接调用std::terminate()终止,这在实际开发中极易出错,尤其是在异常发生时,手动调用很容易被跳过。
  • std::jthread的解决方案std::jthread在其析构函数中会自动判断。如果线程仍在运行且可连接(joinable),它会自动调用join(),等待线程正常结束,从而彻底避免了因忘记join而导致的程序崩溃问题,简化了代码并增强了健壮性。
// 传统 std::thread 需要手动管理std::thread traditional_thread([]{/* 任务 */ });
// 必须手动调用,否则风险很大
traditional_thread.join();// C++20 std::jthread 自动管理
{std::jthread new_thread([]{/* 任务 */ });
// 离开作用域时自动 join,无需手动调用
}

🛑 2. 内建协作式线程取消机制

这是std::jthreadstd::stop_token/std::stop_source组合带来的最关键特性,为线程提供了安全、标准化的停止途径。

  • 传统方式的缺陷:过去,停止一个线程通常需要通过一个共享的布尔标志位(如std::atomic<bool>)来通信。工作线程需要定期检查该标志,主线程则设置该标志以请求停止。这种方式需要开发者自己实现通信逻辑,且无法与条件变量等设施方便地集成。
  • std::stop_token和 std::stop_source
    • std::stop_source:是停止请求的发起方。调用其request_stop()方法即可发出停止信号。
    • std::stop_token:是停止请求的接收方。工作线程通过它来查询(stop_requested())是否收到了停止请求。
    • 它们内部共享一个状态,自动处理所有同步问题。
  • 与 std::jthread的集成:每个std::jthread对象都内建了一个std::stop_source。你可以通过get_stop_token()方法获取与该线程关联的std::stop_token,并传递给线程函数。线程函数只需定期检查停止令牌即可。
void worker(std::stop_token stoken) {while (!stoken.stop_requested()) {
// 执行工作...std::this_thread::sleep_for(1s);}
// 收到停止请求,优雅清理并退出
}int main() {std::jthread my_thread(worker);// 自动传递stop_token给worker函数// ... 其他操作my_thread.request_stop();// 请求线程停止// jthread析构时会自动join,等待线程退出return 0;
}

⚡ 3. 与条件变量协同工作

std::condition_variable_any(是std::condition_variable的更通用版本)提供了接受std::stop_tokenwait重载。这意味着线程可以在等待条件变量时,也能响应停止请求,避免了在等待时无法停止线程的问题。

void waiting_worker(std::stop_token stoken, std::mutex& mtx, std::condition_variable_any& cv) {std::unique_lock lock(mtx);
// 在等待时也同时监听停止请求cv.wait(lock, stoken, []{ return/* 条件 */; });if (stoken.stop_requested()) {
// 处理停止逻辑}
}

🛡️ 4. 增强异常安全性

由于std::jthread实现了自动资源管理,即使在作用域内发生异常,栈回滚(stack unwinding)也会触发其析构函数,确保线程被正确连接(join),从而避免了资源泄漏。这解决了传统std::thread在异常处理场景下的棘手问题。

📊 核心优势对比

特性std::thread(C++11)std::jthread(C++20)
生命周期管理手动调用 join()或 detach(),易出错自动调用 join(),符合RAII,安全
线程取消无内置支持,需自定义标志(如atomic<bool>内置协作式取消 (stop_token/stop_source)
与条件变量协同难以优雅处理“等待时取消”可与condition_variable_any无缝集成
异常安全异常可能导致未定义行为自动管理保障异常安全
设计哲学基础、灵活但繁琐更高级的抽象,开箱即用,更安全

💡 结论与实践建议

std::jthreadstd::stop_token的引入标志着C++多线程编程向更高层次抽象的重要一步。它们通过自动化标准化解决了长期困扰开发者的线程生命周期管理和安全取消问题。

  • 新项目:应**优先考虑使用std::jthread**来代替std::thread,以获得更高的开发效率和代码健壮性。
  • 旧项目迁移:在重构现有代码时,可以将手动管理线程和自定义停止标志的逻辑替换为std::jthreadstd::stop_token,这能简化代码并降低并发缺陷的风险。
  • 注意:停止机制是协作式(cooperative)的,意味着工作线程必须主动查询stop_token并做出响应,才能优雅停止。它无法强制中断一个正在执行计算的线程。

文章转载自:

http://pftSz6eF.rqnzh.cn
http://gWMRI86L.rqnzh.cn
http://ACZG7vxk.rqnzh.cn
http://BeooVbYr.rqnzh.cn
http://XJJ7JHQu.rqnzh.cn
http://fzjee6xi.rqnzh.cn
http://5XyuQK64.rqnzh.cn
http://RpqKTmyb.rqnzh.cn
http://AsK36gUU.rqnzh.cn
http://SsHy5ahT.rqnzh.cn
http://nHtKIg2u.rqnzh.cn
http://48J1ubBk.rqnzh.cn
http://V37tTfMv.rqnzh.cn
http://xFv2VcmM.rqnzh.cn
http://21RcQ09Z.rqnzh.cn
http://2AvC3kE3.rqnzh.cn
http://uyrSlfE6.rqnzh.cn
http://srZLhjwR.rqnzh.cn
http://xenIvHpX.rqnzh.cn
http://g9bxfZ9K.rqnzh.cn
http://bPJ5kH2l.rqnzh.cn
http://4H8NYGVY.rqnzh.cn
http://FrGP7icZ.rqnzh.cn
http://mzTMlg1U.rqnzh.cn
http://83m4HhtW.rqnzh.cn
http://4QtvI0uj.rqnzh.cn
http://0LfPpnrE.rqnzh.cn
http://fNNvxNbI.rqnzh.cn
http://MerJW9gQ.rqnzh.cn
http://wUq4Hlyn.rqnzh.cn
http://www.dtcms.com/a/381553.html

相关文章:

  • 结构光三维重建原理详解(1)
  • window显示驱动开发—视频呈现网络简介
  • Vision Transformer (ViT) :Transformer在computer vision领域的应用(二)
  • 计算机网络的基本概念-2
  • 计算机视觉----opencv实战----指纹识别的案例
  • 【操作系统核心知识梳理】线程(Thread)重点与易错点全面总结
  • JVM之堆(Heap)
  • 【网络编程】TCP 服务器并发编程:多进程、线程池与守护进程实践
  • 智能体赋能金融多模态报告自动化生成:技术原理与实现流程全解析
  • 数据库(一)数据库基础及MySql 5.7+的编译安装
  • 将 x 减到 0 的最小操作数
  • Java 开发工具,最新2025 IDEA使用(附详细教程)
  • 基于STM32单片机的OneNet物联网粉尘烟雾检测系统
  • 注意力机制与常见变种-概述
  • Linux内核TCP协议实现深度解析
  • 数据治理进阶——40页数据治理的基本概念【附全文阅读】
  • Spring Boot 与前端文件下载问题:大文件、断点续传与安全校验
  • 认知语义学中的象似性对人工智能自然语言处理深层语义分析的影响与启示
  • 游戏服务器使用actor模型
  • 002 Rust环境搭建
  • 2.11组件之间的通信---插槽篇
  • 关于java中的String类详解
  • S3C2440 ——UART和I2C对比
  • TDengine 数据写入详细用户手册
  • 校园电动自行车管理系统的设计与实现(文末附源码)
  • HarmonyOS 应用开发深度解析:基于 ArkTS 的现代化状态管理实践
  • 【大语言模型 58】分布式文件系统:训练数据高效存储
  • [code-review] AI聊天接口 | 语言模型通信器
  • 力扣刷题笔记-删除链表的倒数第N个结点
  • 代码审计-PHP专题原生开发SQL注入1day分析构造正则搜索语句执行监控功能定位