C++怎么使用jthread实现自动管理的线程

来源:AI大模型作者:长沙网站建设头衔:草根站长
导读:本期聚焦于小伙伴创作的《C++怎么使用jthread实现自动管理的线程》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《C++怎么使用jthread实现自动管理的线程》有用,将其分享出去将是对创作者最好的鼓励。

C++20标准新增的jthread类是对传统thread的重要升级,它内置了停止令牌机制和自动join特性,不需要开发者手动调用join方法就能保证线程资源被正确回收,同时支持更优雅的线程停止逻辑,非常适合需要长期运行或需要可控停止的线程场景。

C++怎么使用jthread实现自动管理的线程

jthread与传统thread的核心区别

传统thread在使用时需要开发者手动处理线程的回收逻辑,如果忘记调用join或者detach,程序结束时可能会抛出std::system_error异常。而jthread在析构时会自动调用join,同时支持通过停止令牌向线程发送停止请求,两者的核心差异如下:

特性threadjthread
析构行为若未join或detach,析构时抛异常析构时自动调用join,无异常
停止机制无内置停止机制,需自行实现内置停止令牌,支持停止请求
停止回调不支持支持注册停止时的回调函数

基础jthread使用示例

最简单的jthread使用方式和传统thread类似,直接传入可调用对象即可,不需要手动管理生命周期:

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

// 线程执行函数
void worker_task() {
    for (int i = 0; i < 5; ++i) {
        std::cout << "线程执行第" << i << "次任务" << std::endl;
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }
}

int main() {
    // 创建jthread,自动管理生命周期
    std::jthread t(worker_task);
    // 不需要手动调用t.join(),jthread析构时会自动处理
    // 主线程等待3秒后,jthread会随着main函数结束自动析构并join
    std::this_thread::sleep_for(std::chrono::seconds(3));
    return 0;
}

上述代码中,jthread对象t在main函数结束时析构,会自动等待worker_task执行完成,不需要开发者手动调用join方法,避免了遗漏join导致的异常问题。

使用停止令牌控制线程停止

jthread的核心优势之一是内置了std::stop_token,可以向线程发送停止请求,线程可以主动检查停止状态并退出执行。创建jthread时,如果可调用对象的第一个参数是std::stop_token,jthread会自动把停止令牌传递给线程函数:

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

// 带停止令牌的线程函数,第一个参数为std::stop_token
void stoppable_task(std::stop_token st) {
    int count = 0;
    // 循环检查停止令牌的状态
    while (!st.stop_requested()) {
        std::cout << "可停止线程执行第" << count << "次任务" << std::endl;
        ++count;
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }
    std::cout << "收到停止请求,线程退出" << std::endl;
}

int main() {
    // 创建jthread,自动传递停止令牌给stoppable_task
    std::jthread t(stoppable_task);
    // 主线程等待3秒后,调用request_stop发送停止请求
    std::this_thread::sleep_for(std::chrono::seconds(3));
    std::cout << "主线程发送停止请求" << std::endl;
    t.request_stop();
    // 这里不需要手动join,jthread析构时会自动等待线程退出
    return 0;
}

运行上述代码,线程会执行3次任务后,收到主线程的停止请求,然后主动退出循环,最终jthread析构时自动完成join操作。

注册停止回调

除了在线程函数中主动检查停止令牌的状态,jthread还支持通过std::stop_callback注册停止时的回调函数,当停止请求被发送时,回调函数会自动执行,适合需要在线程外处理停止逻辑的场景:

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

void task_with_callback(std::stop_token st) {
    // 注册停止回调,当停止请求到来时执行
    std::stop_callback cb(st, [](){
        std::cout << "停止回调执行:清理线程相关资源" << std::endl;
    });
    int count = 0;
    while (!st.stop_requested()) {
        std::cout << "带回调的线程执行第" << count << "次任务" << std::endl;
        ++count;
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }
}

int main() {
    std::jthread t(task_with_callback);
    std::this_thread::sleep_for(std::chrono::seconds(2));
    std::cout << "主线程发送停止请求" << std::endl;
    t.request_stop();
    return 0;
}

当主线程调用request_stop后,注册的停止回调会首先执行,完成资源清理工作,之后线程函数再检查到停止请求退出循环,整个停止流程更加可控。

使用注意事项

  • jthread是C++20新增特性,需要编译器支持C++20标准,编译时需要添加对应的编译选项,比如GCC需要添加-std=c++20参数。
  • 停止令牌的停止请求是一次性的,一旦发送后状态就会变为已请求,无法重置。
  • 如果线程函数没有接收std::stop_token参数,jthread的停止机制不会生效,此时jthread仅具备自动join的特性。
  • 不要在jthread对象上手动调用join或者detach,否则会触发未定义行为,jthread的设计目标就是自动管理这些操作。

C++20jthread自动线程管理thread修改时间:2026-06-12 09:03:16

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。