jthread是否可以完全取代thread?

C++之线程thread到jthread C++20引入的std::jthread通过RAII机制和协作式取消(stop_token)解决了std::thread的析构安全问题。内置stop_source/stop_token支持优雅终止线程,结合condition_variable_any实现阻塞操作的即时唤醒 阅读详情

​选择 std::thread 的场景​:

  • 需要手动控制生命周期(如延迟 join 或选择性 detach)。
  • 需要避免自动 join 的默认行为(如线程后台运行)。
  • 需要更直观地表达代码意图(如明确手动管理或所有权转移)

线程所有权转移

当需要将线程句柄传递给其他对象管理时(如线程池),std::thread 的移动语义更直接,而 std::jthread 的自动析构行为可能引入意外开销。

class ThreadPool {
public:
    void add_thread(std::thread t) {
        // 接管线程,手动管理生命周期
        threads.push_back(std::move(t));
    }
    ~ThreadPool() {
        for (auto& t : threads) {
            if (t.joinable()) t.join();
        }
    }
private:
    std::vector<std::thread> threads;
};

// 使用 std::thread 明确所有权转移
ThreadPool pool;
std::thread t([]{ /* ... */ });
pool.add_thread(std::move(t)); // 清晰表达所有权转移

// 若用 jthread,析构时自动 join 可能与线程池设计冲突

在多个条件分支中控制线程合并的时机

 

void process_result(int result) { /* ... */ }
void handle_error() { /* ... */ }

bool condition = /* 某个复杂条件 */;

// 使用 std::thread 允许手动控制 join 时机
std::thread worker([]() -> int {
    // 执行耗时计算,返回结果
    return 42;
});

// 主线程执行其他操作...

if (condition) {
    // 条件满足时,立即获取结果(需等待线程完成)
    worker.join();
    int result = /* 获取 worker 的结果 */;
    process_result(result);
} else {
    // 条件不满足时,主线程不等待,worker 继续在后台运行
    worker.detach();
    handle_error();
}

​1. std::jthread 的核心改进

自动线程生命周期管理

std::thread 的问题:

  • 如果std::thread对象在析构时仍可联结(joinable()为true),且未显式调用join()或detach(),则程序会调用std::terminate(),导致崩溃。
  • 需要手动管理线程的合并或分离,容易出错。

std::jthread 的改进:

  • ​析构时自动调用join():若线程未分离且仍可联结,自动合并,避免崩溃。
  • ​支持显式分离​:可通过detach()手动分离线程。
协作式线程中断

功能​:通过request_stop()向线程发送停止请求,线程内部可检查std::stop_token决定是否终止。

std::jthread jt([](std::stop_token st) {
    while (!st.stop_requested()) {
        std::cout << "Working..." << std::endl;
        std::this_thread::sleep_for(1s);
    }
});

// 请求线程停止
jt.request_stop();

避免手动设计线程退出标志(如atomic<bool>),简化代码 

2. std::jthread 的优势场景

需要安全自动合并线程

void func() {
    std::thread t([]{ /* ... */ });
    // 如果此处抛出异常,t 未 join/detach,程序终止!
}

需要协作式中断

// 传统方式(需要原子变量)
std::atomic<bool> stop_flag{false};
std::thread t([&stop_flag]{
    while (!stop_flag.load()) { /* ... */ }
});
stop_flag.store(true);
t.join();

// jthread 方式(无需手动管理)
std::jthread t([](std::stop_token st) {
    while (!st.stop_requested()) { /* ... */ }
});
t.request_stop();

3. std::jthread 的局限性

  • 协作式中断的代价​:std::stop_token和内部状态管理可能引入微小性能损耗。
  • ​适用场景​:对性能极度敏感的场景(如高频实时系统),可能需要权衡是否使用。
无法完全替代手动控制:​
  • ​需要显式分离线程时​:
    std::jthread t([]{ /* ... */ });
    t.detach(); // 仍然需要显式调用
  • ​无需自动合并的场景​:某些设计可能希望线程在后台运行,无需阻塞等待。

4. 何时仍需使用 std::thread?

需要兼容旧版C++标准:

  • 若项目必须支持C++11/14/17,std::thread仍是唯一选择。
无需自动合并或中断功能

需要更轻量级的线程对象

  • std::jthread内部需要维护std::stop_source等状态,占用更多内存(尽管差异通常可忽略)

5. 结论:jthread vs thread

​特性​​std::jthreadstd::thread
自动析构合并✅ 自动调用join()❌ 需手动管理,否则崩溃
协作式中断✅ 支持request_stop()❌ 需手动实现(如原子变量)
内存占用略高(包含stop_source等状态)更低
C++标准支持C++20及以上C++11及以上
适用场景需要安全生命周期管理或协作中断兼容旧标准、无需自动管理或中断

6. 补充:std::this_thread 

是 C++ 标准库 <thread> 头文件里的一个命名空间,它提供了一系列用于操作当前线程的实用函数。

std::this_thread::sleep_for

此函数可让当前线程休眠指定的时长。

#include <iostream>
#include <thread>
#include <chrono>

int main() {
    std::cout << "Sleeping for 2 seconds..." << std::endl;
    // 当前线程会休眠 2 秒,之后再继续执行后续代码。
    std::this_thread::sleep_for(std::chrono::seconds(2));
    std::cout << "Woke up after 2 seconds." << std::endl;
    return 0;
}

std::this_thread::sleep_until 

#include <iostream>
#include <thread>
#include <chrono>

int main() {
    auto wake_time = std::chrono::steady_clock::now() + std::chrono::seconds(2);
    std::cout << "Sleeping until the specified time..." << std::endl;
    // 当前线程会休眠到 wake_time 这个时间点,然后再接着执行后续代码。
    std::this_thread::sleep_until(wake_time);
    std::cout << "Woke up at the specified time." << std::endl;
    return 0;
}

std::this_thread::yield 

#include <iostream>
#include <thread>

void threadFunction() {
    for (int i = 0; i < 5; ++i) {
        std::cout << "Thread: " << i << std::endl;
        // 让线程在每次循环时主动放弃 CPU 时间片,从而让其他线程有机会执行。
        std::this_thread::yield();
    }
}

int main() {
    std::thread t(threadFunction);
    for (int i = 0; i < 5; ++i) {
        std::cout << "Main: " << i << std::endl;
    }
    t.join();
    return 0;
}

std::this_thread::get_id 

返回当前线程的唯一标识符

#include <iostream>
#include <thread>

void threadFunction() {
    std::cout << "Thread ID: " << std::this_thread::get_id() << std::endl;
}

int main() {
    std::thread t(threadFunction);
    std::cout << "Main Thread ID: " << std::this_thread::get_id() << std::endl;
    t.join();
    return 0;
}
CLIP-Count代码配置以及踩坑记录 阅读详情

相关推荐

Jetson Orin Nano Super开发板实战:视觉模型部署与性能优化指南

本文详细介绍了Jetson Orin Nano Super开发板在边缘AI视觉模型部署与性能优化的完整实战指南。内容涵盖JetPack 6.1环境配置、Docker容器化部署、YOLO11及Transformer模型的TensorRT优化技巧,并通过实测数据展示了性能提升与功耗管理策略,为开发者提供高效的视觉AI部署解决方案。

7h6j5k4l3的博客 1196

有了std::thread,为什么还需要引入std::jthread?

C++11以来提供了C++原生的多线程std::thread,这极大的方便了多线程的书写。在此之前书写多线程时需要平台原生API,这对于跨平台尤其是跨多平台程序来讲,多线程部分代码书写及维护都是极大的工作量。}};运行如上代码时,会出现崩溃,堆栈信息如下:由如上堆栈信息可知,崩溃原因为std::thread在析构时,如果对象仍为joinable状态,则会触发中断,为避免崩溃需要在std::thread析构器前需要将其置于非joinable状态,即需要主动调用join或detach接口。

红军不怕远征难,万水千山只等闲 1905

5分钟搞定Conflux钱包注册:Fluent钱包从安装到转账全流程指南

本文提供Conflux公链上Fluent钱包的完整注册和使用指南,涵盖从安装、助记词备份到CFX转账的全流程。特别强调安全操作要点,包括助记词保管和网络选择,帮助用户5分钟内快速掌握这款国产公链钱包的核心功能,确保数字资产安全。

weixin_29181861的博客 244

《C++并发编程》之正确使用thread和jthread

C++11从语言层面引入了多线程编程的能力,使得开发者可以通过标准库提供的 thread 等库实现跨平台的多线程编码。标准库中的 thread 等库为开发者屏蔽了不同平台下的多线程实现细节,提供了统一的编程接口,并且可以和标准库中的其它库一同使用,提高程序的开发效率。

升级打怪记录 1338

开源光标主题实战:从Moshi Monsters到自定义指针的完整指南

光标主题是操作系统个性化的重要组成部分,它通过替换系统默认指针图标来改变视觉交互体验。其原理在于操作系统允许用户自定义指针资源文件,这些文件定义了不同状态下的光标图像。从技术价值看,一套设计良好的光标主题不仅能提升桌面美观度,还能增强用户的情感连接和操作愉悦感,是低成本高回报的数字幸福感提升方案。在应用场景上,无论是开发者、设计师还是普通用户,都可以通过更换光标主题来个性化工作环境。本文以热门的Moshi Monsters开源光标项目为例,深入解析了光标主题的设计逻辑、系统适配方案以及二次创作方法,涵盖了W

weixin_30879833的博客 564

11、rsa-目标主机支持RSA密钥交换【原理扫描】的漏洞

通过将 etcd 的 TLS 密钥交换算法从 RSA 升级为 ECDHE,可实现前向保密,彻底消除 “私钥泄露导致历史流量解密” 的风险。核心步骤是通过强制启用含ECDHE的套件,并禁用 RSA 密钥交换套件,同时建议升级到 TLS 1.2+ 并优化证书类型(优先 ECDSA)。这一配置符合云原生安全最佳实践,也是 Kubernetes 等依赖 etcd 的系统推荐的安全标准。生成临时密钥的具体步骤是什么?如何验证etcd是否已成功更新为ECDH密钥交换算法?配置临时密钥交换算法可能带来哪些性能影响。

xuebo1129927648的博客 1万+

C++20 jthread

vs2019 C++20 jthread01 jthread的一个实现02 jthread用法02.01 cppreference上面的介绍02.02 可协作中断的用法02.03 NICOLAI JOSUTTIS提供了大量测试用例 jthread是有自动合并和取消支持的 std::thread。jthread包装了一下thread,提供了线程运行中停止的接口。jthread定义在<threa...

一朵花开的时间 3754

【用unity实现100个游戏之2】复刻实现经典2d平台跳跃游戏《蔚蓝 Celeste》(附工程源码)

蔚蓝》是一款备受好评的独立游戏,由游戏开发工作室开发并由发行。这款游戏于2016年首次发布,并在玩家和评论界收获了广泛赞誉。蔚蓝以其独特的艺术风格和引人入胜的故事而著称。游戏以深海为背景,玩家将扮演一个能够探索水下世界的神秘生物。游戏通过惊人的视觉表现和动态的海洋生态系统为玩家带来了令人难忘的游戏体验。无论是广阔的水下景观还是充满生机的海洋生物,蔚蓝都让玩家感受到深海的神秘和美丽。蔚蓝在玩法上注重探索和解谜。玩家可以在海底环境中自由游动,发现隐藏的地点和秘密,与各种生物互动,并解决环境谜题以继续前进。

向宇的博客,专注php/web全栈 unity游戏开发,欢迎大家评论纠错 4167

C++ 中 jthread 和 thread 的区别?

是 C++20 的一部分,因此可能不是所有环境都可用。在选择使用哪一个时,需要考虑你的项目需求以及编译器的支持情况。(自 C++20 起引入)是用于创建和管理线程的两种不同的类模板。更高级的特性,特别是在异常安全性和线程中断方面。

m0_63331248的博客 575

Python控制Keysight DAQ973A/DAQ970A实现数据采集

本文介绍了如何通过编程实现Keysight DAQ973A数据采集系统的自动化温度测量。首先,通过GPIB线将PC与仪器连接,并使用热电耦测量线连接被测装置。接着,通过查阅Keysight官网提供的编程手册,获取了实现温度测量所需的SCPI指令。然后,使用pyvisa库编写代码,与仪器进行交互,发送SCPI指令并读取测量结果。代码中整合了配置和查询指令,并将测量结果转换为浮点数格式。最后,将整个流程封装为命令行工具,用户可以通过配置文件设置参数,并执行自动化测试,测试结果将保存为CSV文件。整个过程实现了温

xgh1951的博客 1887

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

std::jthread与std::thread区别

​std::jthread是C++20新引入的线程类,与 std::thread 类似,或者说,jthread是对thread进一步的封装,功能更强大​。 ​std::jthread的​j实际上是​joining的缩写​,​众所周知,std::thread在其生命周期结束时调用join()(让主线程等待该子线程完成,然后主线程再继续执行,对于不会停止的线程,不要使用join(),防止阻塞其他线程),或调用detach()(调用detach()进行线程分离,使其不影响其他线程运行,比如一个线程中无限循环执行

大牛直播SDK 1105

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

C++20中的jthread

其实还有几个特点值得说说,但不准备再讲了,虽然已经投票完成确定了c++20的标准,但毕竟还没有正式增加进去,大家有兴趣可以看看源码。整体来看,c++应用还是越来越方便,这对c++来说,肯定是个好事情。现在就希望>VS2019或者>GCC11中,尽快完全支持。

fpcc的专栏 1492

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

C++ std::thread 和 std::jthread 使用详解 (含C++20新特性)

在C++ 11之前,官方并没有支持线程库。在Linux下完成多线程编程时,多数情况下是使用#include <pthread.h>的函数。C++ 11通过标准库引入了对thread类的支持,大大方便了完成多线程开发的工作。在C++20中,引入的jthread类是thread自动合并和取消的实现版本。接下来将先从线程函数和thread类开始介绍,分析它们的不同,然后再介绍jthread。 std::thread 定义于头文件<thread> classt...

Tyler_Zx的博客 1万+

C++20(jthread)

本章参考和 MSVC 示例。类表示。它与具有相同的通用行为,除了jthread在析构时会自动加入,并且可以在某些情况下被取消/停止。与传统的 std::thread 的不同。

CD200309的博客 986

【C++20】std::thread 和 std::jthread 使用详解

(0x01) std::thread 类创建线程非常方便,构造 thread 对象时传入一个需要运行的函数及其参数。构造完成后,新的线程马上被创建,同时执行该对象。注意:若需要传递引用参数给线程函数,则必须包装它(例如用std::ref 或 std::cref(0x02)使用 std::thread 默认的构造函数构造对象时,该对象是不关联任何线程的。可以在之后的使用过程中再关联到某一线程。可以通过使用 joinable() 接口,判断一个 thread 对象是否关联某个线程。(0x03)

qq_43331089的博客 589

c++20 jthread的理解

c++20 jthread的理解

小x的博客 950

C++ 20新特性之线程与jthread

C++ 20中新引入的std::jthread解决了C++ 11中std::thread的一些不便之处,特别是在线程生命周期管理上的自动化处理。std::jthread是一个智能指针风格的类,它自动join或detach与之关联的线程,从而避免了潜在的资源泄露问题。

hope_wisdom的技术博客 1840

std::jthread与std::thread的区别

特性上,std::jthread相比std::thread主要增加了以下两个功能: 1.std::jthread对象被destruct时,会自动调用join,等待其所表示的执行流结束。 2.支持外部请求中止(通过get_stop_source、get_stop_token和request_stop)。 为什么不是选择往std::thread添加新接口,而是引入了一个新的标准库? 因为std::jthread为了实现上述新功能,带来了额外的性能开销(主要是多了一个成员变量)。而根据C++一直以来“不为

danshiming的博客 1366

C++ 中 std::jthread 与 std::thread 的区别:C++20 线程管理的进化

不是的颠覆性替代,而是在其基础上的重要改进。自动 join 解决安全问题jthread在析构时自动 join,从根本上消除了thread析构时因忘记 join/detach 导致程序崩溃的风险。这使得 C++ 线程管理第一次真正实现了 RAII 友好的设计。stop_token 实现优雅取消jthread内置的 stop_token 机制提供了标准化的协作式线程取消方案。被取消的线程可以优雅地完成清理工作,而不是被强制终止。这比使用原子 bool 标志或条件变量更加标准化和可靠。完全向下兼容。

✨ 欢迎来到【Seal ^_^ 的优快云博客】!✨ 453

JTHREAD剖析

1.JTHREAD介绍 实际项目中经常会涉及到多线程架构。为了给WINUX(Windows+Linux)平台提供一套相同的操作线程的接口,需要将平台上对线程操作的API封装成一个的通用类。JTHREAD即是这样的一个开源类库。 JTHREAD是很简单的,主要包含JThread类和JMutex类,它们分别代表一个线程和一个互斥体,互斥体是为了同步多线程通信。该开发包作了简单的跨平台实现,对于*N

老衲不出家 1529

【C++】jthread:优雅终止线程新方案

C++20引入jthread和协作中断机制,解决了传统线程管理的三大痛点:1)提供标准化的协作中断机制(stop_token/stop_source),无需手动实现标志位轮询;2)自动管理线程生命周期,析构时自动join避免程序崩溃;3)统一中断接口,支持中断回调(stop_callback)实现资源清理。这些改进显著提升了线程安全性和代码可维护性。

Ape's IT Blog 1049

回顾 C++20 的 std::jthread:简化多线程编程的利器

在 C++11 中,`std::thread` 被引入来简化多线程编程,允许开发者以一种相对简单的方式创建并管理线程。然而,使用 `std::thread` 时,有一个需要特别注意的问题:**必须手动管理线程的生命周期**。线程在创建之后,如果没有显式地调用 `join()` 或 `detach()`,程序退出时将会导致未定义行为。这就给线程管理带来了额外的复杂性和潜在的内存泄漏风险。

探索C++编程的奥秘,分享深入的技术见解和实践,旨在激发读者创造力与解决问题的思维。 1563

C++20中线程类std::jthread的使用

C++20中线程类std::jthread的使用

网络资源是无限的 987

新的线程:C++20 std::jthread

jthread基于jthread对象被析构时,会自动调用join,等待其所表示的执行流结束。jthread支持外部请求中止(通过和中的自动join和外部请求中止功能使编写更安全的代码变得更加容易,但其性能上相对于thread也增加了开销。iDoitnow如果喜欢话,可以关注一下。

jianmo的博客 1455

[预告]全面解析thread 与 jthread

大家好,我是光城,最近有小伙伴让我讲一下thread,于是安排起来了,写了几千字的文章。想象一下,一起直播看gcc-13源码,一起学习C++11、C++20的源码是多么的有趣,本次讲解的内容将会带大家深入gcc-13的源码,从C++ 11到C++20,一起揭秘thread与jthread,非常硬核,到时候也欢迎大家一起交流。这次也打算尝试做一次付费直播,时间暂定5.7晚8点,感兴趣的私聊我发10....

Francis的博客 260
上一篇: [C++面试] 初始化相关面试点深究
下一篇: [C++面试] lambda面试点
冰箱里有碗
博客等级 码龄3年 425粉丝 89原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值