面试题:C++ 中 jthread 和 thread 的区别?

在 C++20 中引入了 std::jthread,它是 std::thread 的增强版本,主要区别在于 std::jthread 提供了更安全和更方便的线程管理功能,特别是自动线程回收协作中断支持

以下是 std::jthread 和 std::thread 的主要区别:


1. 自动线程回收(RAII 支持)

  • std::thread
    • 如果 std::thread 对象在析构时仍然是可连接的(即线程仍在运行),程序会调用 std::terminate,导致程序终止。
    • 需要手动调用 join() 或 detach() 来避免这种情况。
  • std::jthread
    • 在析构时,如果线程仍然是可连接的,std::jthread 会自动调用 join(),等待线程结束。
    • 这种行为符合 RAII(资源获取即初始化)原则,避免了资源泄漏和程序崩溃。

示例:

#include <iostream>
#include <thread>

void task() {
    std::this_thread::sleep_for(std::chrono::seconds(2));
    std::cout << "Task completed!" << std::endl;
}

int main() {
    {
        std::thread t(task); // 如果 t 在析构时未 join 或 detach,程序会崩溃
        // t.join(); // 必须手动调用 join()
    } // 这里 t 析构时,如果未 join 或 detach,程序会终止

    {
        std::jthread jt(task); // jthread 在析构时会自动 join
    } // 这里 jt 析构时,会自动等待线程结束

    return 0;
}

2. 协作中断支持

  • std::thread
    • 不提供内置的线程中断机制。
    • 如果需要中断线程,通常需要手动实现(例如通过标志位或条件变量)。
  • std::jthread
    • 提供了协作式线程中断机制,通过 std::stop_token 和 std::stop_source 实现。
    • 线程可以定期检查 std::stop_token,以响应中断请求。

示例:

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

void task(std::stop_token token) {
    while (!token.stop_requested()) {
        std::cout << "Working..." << std::endl;
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }
    std::cout << "Task interrupted!" << std::endl;
}

int main() {
    std::jthread jt(task); // 启动线程

    std::this_thread::sleep_for(std::chrono::seconds(3));
    jt.request_stop(); // 请求中断线程

    return 0;
}

3. 接口兼容性

  • std::thread
    • 提供了基本的线程管理接口,如 join()detach() 和 get_id()
    • 需要手动管理线程的生命周期。
  • std::jthread
    • 完全兼容 std::thread 的接口,可以直接替换 std::thread
    • 额外提供了 request_stop() 和 get_stop_token() 等接口,用于协作中断。

4. 总结对比

特性std::threadstd::jthread
自动线程回收不支持(需手动 join 或 detach支持(析构时自动 join
协作中断支持不支持支持(通过 stop_token 实现)
接口兼容性基本线程管理接口完全兼容 std::thread,额外提供中断接口
适用场景需要手动管理线程生命周期的场景需要自动管理和协作中断的场景

5. 使用建议

  • 如果需要简单的线程管理,且不涉及复杂的生命周期管理,可以使用 std::thread
  • 如果需要更安全的线程管理(自动回收)或协作中断功能,优先使用 std::jthread

在面试中,理解 std::jthread 的优势并能够解释其与 std::thread 的区别是非常重要的。

THE END
点赞10 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容