std::thread 在析构时未 join 或 detach 导致程序崩溃,如何安全封装?

我发现在 C++ 中,如果 std::thread 对象在析构时既没有被 join() 也没有被 detach(),程序会调用 std::terminate 崩溃。

我希望了解一种安全的 RAII 封装方式,能够在线程对象析构时自动处理线程的生命周期,同时提供灵活的策略选择(例如:自动等待完成、自动分离、或主动取消)。
运行环境:
编译器:GCC 11.4 / Clang 15
C++ 标准:C++17 或 C++20
操作系统:Ubuntu 22.04
示例代码

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

void worker() {
    std::this_thread::sleep_for(std::chrono::seconds(2));
    std::cout << "worker done\n";
}

int main() {
    std::thread t(worker);
    // 忘记调用 t.join() 或 t.detach()
    // t 析构时程序崩溃
    return 0;
}

运行结果

我希望了解以下几种方案的实现方式及各自的优缺点:

1、RAII 封装类:在析构函数中自动调用 join()
2、策略可配置:支持在构造时指定析构行为(join / detach / 不做任何操作)
3、支持线程取消:如何优雅地请求线程退出(例如使用 std::jthread 或自定义停止令牌)

特别希望看到:

  • 完整的可运行代码示例
  • 不同策略的适用场景说明
  • 如果使用 C++20 的 std::jthread,是否完全解决了这个问题?