0

0

c++的std::jthread如何自动join线程_c++20 RAII风格的线程管理

裘德小鎮的故事

裘德小鎮的故事

发布时间:2025-11-30 14:06:06

|

961人浏览过

|

来源于php中文网

原创

std::jthread通过自动join和协作式中断提升线程安全性,其析构时自动等待线程结束,避免因未手动调用join导致的程序终止,同时支持通过stop_token请求取消线程执行,实现更安全、简洁的RAII式多线程编程。

c++的std::jthread如何自动join线程_c++20 raii风格的线程管理

在C++20中,std::jthread 是对传统 std::thread 的改进,它实现了RAII(Resource Acquisition Is Initialization)风格的线程管理,最关键的一点是:当 jthread 对象被销毁时,会自动调用 join(),避免程序因未正确等待线程结束而崩溃。

为什么需要 jthread?

在 C++11 到 C++17 中使用 std::thread 时,必须手动调用 join()detach()。如果忘记这么做,线程对象在析构时会触发 std::terminate(),导致程序直接退出。

jthread 解决了这个问题——它在析构函数中自动调用 join(),确保线程安全地等待结束,无需开发者显式处理。

自动 join 的实现机制

std::jthread 在内部维护一个线程对象和一个停止令牌(stop token),其析构函数定义如下逻辑:

LongCat AI
LongCat AI

美团推出的AI对话问答工具

下载

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

  • 如果线程处于 joinable() 状态(即还在运行或未被等待),则自动调用 join()
  • 不再要求程序员记住是否已等待线程结束
  • 避免因异常路径导致提前退出而遗漏 join
示例代码:
#include 
#include 
#include 

void worker() {
    for (int i = 0; i < 5; ++i) {
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
        std::cout << "Working... " << i << "\n";
    }
}

int main() {
    std::jthread t(worker); // 启动线程

    // 不需要写 t.join()!
    // 当 t 离开作用域时,自动调用 join()

    std::cout << "Main exits, jthread will join automatically.\n";
    return 0;
} // t 被销毁,自动阻塞等待 worker 完成

支持协作式中断的线程取消

std::jthread 还引入了停止机制,允许外部请求线程停止执行:

  • 通过 request_stop() 发送停止信号
  • 线程函数可接收 std::stop_token 并定期检查是否应退出
  • 实现安全、协作式的线程终止
带中断检测的示例:
void cancellable_worker(std::stop_token stoken) {
    for (int i = 0; i < 100; ++i) {
        if (stoken.stop_requested()) {
            std::cout << "Worker cancelled.\n";
            return;
        }
        std::this_thread::sleep_for(std::chrono::milliseconds(50));
        std::cout << "Step " << i << "\n";
    }
}

int main() {
    std::jthread t(cancellable_worker);

    std::this_thread::sleep_for(std::chrono::milliseconds(200));
    t.request_stop(); // 请求停止

    // 析构时仍会自动 join
    return 0;
}

与 std::thread 的关键区别

  • 自动 join:jthread 析构即 join,thread 必须手动操作
  • 可取消性:jthread 支持 request_stop,thread 没有内置取消机制
  • RAII 更安全:异常安全更强,资源泄漏风险更低

基本上就这些。用 std::jthread 可以写出更简洁、更安全的多线程代码,尤其适合短生命周期线程或异常频繁的场景。不复杂但容易忽略的是:它不只是“自动 join”,更是现代 C++ 强调的“资源即对象”理念的体现。

相关专题

更多
resource是什么文件
resource是什么文件

Resource文件是一种特殊类型的文件,它通常用于存储应用程序或操作系统中的各种资源信息。它们在应用程序开发中起着关键作用,并在跨平台开发和国际化方面提供支持。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

149

2023.12.20

登录token无效
登录token无效

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

6101

2023.09.14

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

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

810

2023.09.14

token怎么获取
token怎么获取

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

1063

2023.12.21

token什么意思
token什么意思

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

1269

2024.03.01

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

482

2023.08.10

Python 多线程与异步编程实战
Python 多线程与异步编程实战

本专题系统讲解 Python 多线程与异步编程的核心概念与实战技巧,包括 threading 模块基础、线程同步机制、GIL 原理、asyncio 异步任务管理、协程与事件循环、任务调度与异常处理。通过实战示例,帮助学习者掌握 如何构建高性能、多任务并发的 Python 应用。

143

2025.12.24

java多线程相关教程合集
java多线程相关教程合集

本专题整合了java多线程相关教程,阅读专题下面的文章了解更多详细内容。

3

2026.01.21

Java编译相关教程合集
Java编译相关教程合集

本专题整合了Java编译相关教程,阅读专题下面的文章了解更多详细内容。

9

2026.01.21

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
10分钟--Midjourney创作自己的漫画
10分钟--Midjourney创作自己的漫画

共1课时 | 0.1万人学习

Midjourney 关键词系列整合
Midjourney 关键词系列整合

共13课时 | 0.9万人学习

AI绘画教程
AI绘画教程

共2课时 | 0.2万人学习

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

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号